{"record":{"id":"7a3aa373287060b2","repo":"quarkusio/quarkus","slug":"could-not-obtain-principal","errorCode":null,"errorMessage":"Could not obtain principal","messagePattern":"Could not obtain principal","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/QuarkusDirContextFactory.java","lineNumber":66,"sourceCode":"        return createDirContext(securityPrincipal, charPassword, mode);\n    }\n\n    @Override\n    public DirContext obtainDirContext(CallbackHandler handler, ReferralMode mode) throws NamingException {\n        NameCallback nameCallback = new NameCallback(\"Principal Name\");\n        PasswordCallback passwordCallback = new PasswordCallback(\"Password\", false);\n\n        try {\n            handler.handle(new Callback[] { nameCallback, passwordCallback });\n        } catch (Exception e) {\n            throw new RuntimeException(\"Could not obtain credential\", e);\n            //            throw log.couldNotObtainCredentialWithCause(e);\n        }\n\n        String securityPrincipal = nameCallback.getName();\n\n        if (securityPrincipal == null) {\n            throw new RuntimeException(\"Could not obtain principal\");\n            //            throw log.couldNotObtainPrincipal();\n        }\n\n        char[] securityCredential = passwordCallback.getPassword();\n\n        if (securityCredential == null) {\n            throw new RuntimeException(\"Could not obtain credential\");\n            //            throw log.couldNotObtainCredential();\n        }\n\n        return createDirContext(securityPrincipal, securityCredential, mode);\n    }\n\n    private DirContext createDirContext(String securityPrincipal, char[] securityCredential, ReferralMode mode)\n            throws NamingException {\n        final ClassLoader oldClassLoader = setClassLoaderTo(targetClassLoader);\n        try {\n            Hashtable<String, Object> env = new Hashtable<>();","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/elytron-security-ldap/runtime/src/main/java/io/quarkus/elytron/security/ldap/QuarkusDirContextFactory.java#L48-L84","documentation":"After handling the callbacks in QuarkusDirContextFactory.obtainDirContext, the code reads nameCallback.getName(); if null (no principal was supplied), it throws RuntimeException('Could not obtain principal'). The callbacks were 'handled' without error but the handler never set a name, so an LDAP bind DN is unavailable and the DirContext cannot be created.","triggerScenarios":"The CallbackHandler handles the callbacks but never calls nameCallback.setName(...) — e.g. the configured bind DN property is missing/blank, or a custom handler only sets the password.","commonSituations":"quarkus.elytron.security.ldap bind DN (dir-context principal) omitted from configuration; empty string config value; custom credential supplier returning null name; env-specific config file missing the property (works locally, fails in CI/prod).","solutions":["Set the LDAP bind principal in configuration (quarkus.elytron.security.ldap.dir-context.principal) to a valid DN.","If a custom CallbackHandler is used, ensure it calls nameCallback.setName(...) with the full bind DN.","Validate configuration at startup (fail fast if the principal property is blank) rather than at first authentication.","Check environment-specific profiles: the property may be present locally but missing in the deployed profile."],"exampleFix":"// before (application.properties): principal missing\nquarkus.elytron.security.ldap.dir-context.url=ldap://localhost:10389\n// after\nquarkus.elytron.security.ldap.dir-context.url=ldap://localhost:10389\nquarkus.elytron.security.ldap.dir-context.principal=uid=admin,ou=system","handlingStrategy":"validation","validationCode":"// fail fast if the bind DN is missing before LDAP operations\nString bindDn = config.dirContext().principal();\nif (bindDn == null || bindDn.isBlank()) {\n    throw new IllegalStateException(\"quarkus.elytron.security.ldap.dir-context.principal is not set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    DirContext ctx = dirContextFactory.obtainDirContext();\n} catch (RuntimeException e) {\n    if (\"Could not obtain principal\".equals(e.getMessage())) {\n        throw new DeploymentException(\"LDAP bind principal missing from configuration\", e);\n    }\n    throw e;\n}","preventionTips":["Always set quarkus.elytron.security.ldap.dir-context.principal to a full DN.","Add startup-time config validation for all LDAP properties.","Check per-profile config files so prod/CI don't silently drop the property.","If using a custom CallbackHandler, assert nameCallback.getName() != null in tests."],"tags":["ldap","elytron","security","configuration","missing-property"],"backgroundTag":"missing-config-property","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}