SNMP v3 Trap listener not working for AuthNoPriv both MD5 and SHA

Trap listener implementation

TransportMapping<UdpAddress> trapTransport = new DefaultUdpTransportMapping(new UdpAddress("0.0.0.0/<some_port>"));
		snmp = new Snmp(trapTransport);
		snmp.addCommandResponder(this::processTrap);
		MessageDispatcherImpl messageDispatcher = (MessageDispatcherImpl) snmp.getMessageDispatcher();
		messageDispatcher.addAuthenticationFailureListener(this::processFailedTrap);
		USM usm = new USM();
		SecurityModels.getInstance().addSecurityModel(usm);
		SecurityProtocols.getInstance().addPredefinedProtocolSet(SecurityProtocols.SecurityProtocolSet.maxCompatibility);
		snmp.listen();

Adding USM users like this

		// noAuthPriv
		OctetString noAuthSecurityName = new OctetString("ADMIN");
		byte[] noAuthSecurityEngineID = makeEngineId("some valid value");
		UsmUser noAuthUser = new UsmUser(noAuthSecurityName, null, null, 
				null, null, OctetString.fromByteArray(noAuthSecurityEngineID));
		snmp.getUSM().addUser(noAuthUser);

		// AuthNoPriv with "MD5"
		OctetString MD5SecurityName = new OctetString("ADMIN");
		byte[] MD5securityEngineID = makeEngineId("some valid value 1");
		UsmUser MD5User = new UsmUser(MD5SecurityName, AuthMD5.ID, new OctetString("ADMINTEST"),
				null, null, OctetString.fromByteArray(MD5securityEngineID));
		snmp.getUSM().addUser(MD5User);

I am sure that protocols and password are same on network device and in USM user, still for authNoPriv getting below error, working for case with noAuthPriv

Received Failed Trap: 1408, org.snmp4j.asn1.BERInputStream@3b7a6a2a, SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE

Am I missing something in implementation?

Just to mention: trap with same config is processed successfully in pysnmp (Python SNMP v3 library)

I assume that the engine id handling is not correct.

Engine Id handling was correct, found the issue in above implementation for authNoPriv, authpassphrase was not getting localized and used directly causing mismatch and wrong digest error
Below FAQ showed correct way:

@AGENTPP On the side note, can you please help on below

I am setting the Constant Engine id in USM() as below

        // add usm object
		SecurityProtocols securityProtocols = SecurityProtocols.getInstance();
		OctetString ConstantEngineId = OctetString.fromHexStringPairs("ConstantEngineID made with enterprise id and all in format 80xxxx");
		USM usm = new USM(securityProtocols, ConstantEngineId, 0);
		SecurityModels.getInstance().addSecurityModel(usm);

		// Add needed security protocols - we can add all in one go as well, will explore later.
		securityProtocols.addAuthenticationProtocol(new AuthMD5());
		securityProtocols.addAuthenticationProtocol(new AuthSHA());
		securityProtocols.addPrivacyProtocol(new PrivDES());
		securityProtocols.addPrivacyProtocol(new Priv3DES());
		securityProtocols.addPrivacyProtocol(new PrivAES128());

And added USM user for noAuthPriv like below

	    // NoAuthPriv
		OctetString engineId = OctetString.fromHexStringPairs("Agent's engine id");
		UsmUser noAuthPrivUser = new UsmUser(securityName, null, null,
				null, null);
		noAuthPrivUser = noAuthPrivUser.localizeUser(engineId, null, null, securityProtocols);
		snmp.getUSM().addUser(noAuthPrivUser);

But When Inform is received I am getting unknown engine id: ‘’" error (1410)

As I have written in the quoted text above, you need to exactly set the engine ID of the user to the engine ID of the notification receiver.

@AGENTPP
In case if multiple agents have same authpassphrase and privpassphrase for different protocols, say

  1. agent 1 is configured with MD5 and AES-128 with authpassphrase and privpassphrase both as “TestingPassword”
  2. agent 2 is configured with MD5 and DES with authpassphrase and privpassphrase both as “TestingPassword”
    Both agents are configured with SNMP4J notification receiver’s engine-id (i.e. local engine-id) to send informs with.

Then adding entry in USM users like below

    // authPriv with "MD5" and "AES-128"
	OctetString authPrivMD5AES128EngineId = OctetString.fromHexStringPairs("Constant Engine Id");
	UsmUser authPrivMD5AES128User = new UsmUser(securityName, AuthMD5.ID, authAndPrivKey, PrivAES128.ID,
			authAndPrivKey);
	authPrivMD5AES128User = authPrivMD5AES128User.localizeUser(authPrivMD5AES128EngineId, null,
			null, secProtocols);
	snmp.getUSM().addUser(authPrivMD5AES128User);

    // authPriv with "MD5" and "DES"
	OctetString authPrivMD5DESEngineId = OctetString.fromHexStringPairs("Constant Engine Id");
	UsmUser authPrivMD5DESUser = new UsmUser(securityName, AuthMD5.ID, authAndPrivKey, PrivDES.ID,
			authAndPrivKey);
	authPrivMD5DESUser = authPrivMD5DESUser.localizeUser(authPrivMD5DESEngineId, null,
			null, secProtocols);
	snmp.getUSM().addUser(authPrivMD5DESUser);

USM user table will have only one entry that is of the last user added, so how does it will authenticate the messages from agent 1 with different protocols?

What you are trying, is not supported by SNMP(v3). The same security name (= username) cannot be used with different credentials on the same SNMPv3 engine (ID).