{"record":{"id":"e3c2c508b58f477e","repo":"kestra-io/kestra","slug":"both-username-and-password-must-be-provided-if-eit","errorCode":null,"errorMessage":"Both username and password must be provided if either is present: please configure both 'kestra.tasks.sdk.authentication.username' and 'kestra.tasks.sdk.authentication.password' properties","messagePattern":"Both username and password must be provided if either is present: please configure both 'kestra\\.tasks\\.sdk\\.authentication\\.username' and 'kestra\\.tasks\\.sdk\\.authentication\\.password' properties","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"core/src/main/java/io/kestra/core/runners/RunContextSDKFactory.java","lineNumber":39,"sourceCode":"\n        SDKImpl(ApplicationContext applicationContext) {\n            this.sdkAuthentication = applicationContext.getProperty(API_TOKEN_PROP, String.class)\n                .map(it -> new SDK.Auth(Optional.of(it), Optional.empty(), Optional.empty()))\n                .orElseGet(() ->\n                {\n                    Optional<String> maybeUserName = applicationContext\n                        .getProperty(USERNAME_PROP, String.class)\n                        .filter(username -> !username.isBlank()); // to avoid Optional.of(\"\")\n\n                    Optional<String> maybePassword = applicationContext\n                        .getProperty(PASSWORD_PROP, String.class)\n                        .filter(password -> !password.isBlank()); // to avoid Optional.of(\"\")\n\n                    if (maybePassword.isPresent() && maybeUserName.isPresent()) {\n                        return new SDK.Auth(Optional.empty(), maybeUserName, maybePassword);\n                    }\n                    if (maybeUserName.isPresent() || maybePassword.isPresent()) {\n                        throw new IllegalArgumentException(\n                            \"Both username and password must be provided if either is present: please configure both '\" + USERNAME_PROP + \"' and '\" + PASSWORD_PROP + \"' properties\"\n                        );\n                    }\n                    return null;\n                });\n        }\n\n        @Override\n        public Optional<Auth> defaultAuthentication() {\n            return Optional.ofNullable(this.sdkAuthentication);\n        }\n    }\n}\n","sourceCodeStart":21,"sourceCodeEnd":53,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/RunContextSDKFactory.java#L21-L53","documentation":"Thrown while constructing the `RunContextSDKFactory`'s default authentication when the SDK auth config has only ONE of `kestra.tasks.sdk.authentication.username` / `kestra.tasks.sdk.authentication.password` set (the other is blank or absent). Both must be present together; an API token alone is also valid (handled separately) but a lone username or lone password is not. Thrown as `IllegalArgumentException` during bean construction, so it fails application startup.","triggerScenarios":"Configuring `kestra.tasks.sdk.authentication.username` without `.password`, or vice-versa, in `application.yml`. Because the check runs in the `SDKImpl` constructor (a `@Singleton` bean), the error surfaces at Micronaut context startup — Kestra will fail to boot.","commonSituations":"Setting up script/task SDK auth and forgetting one half of the basic-auth pair; migrating from API-token auth to username/password and leaving a stale property; environment-variable override that only sets one of the two.","solutions":["Set BOTH `kestra.tasks.sdk.authentication.username` and `kestra.tasks.sdk.authentication.password`.","Or remove both and use `kestra.tasks.sdk.authentication.api-token` instead.","Or remove all three to run without default SDK auth.","Check for partial env-var overrides (e.g. only `KESTRA_TASKS_SDK_AUTHENTICATION_USERNAME` exported)."],"exampleFix":"# before — only username set\nkestra:\n  tasks:\n    sdk:\n      authentication:\n        username: admin\n\n# after — both set\nkestra:\n  tasks:\n    sdk:\n      authentication:\n        username: admin\n        password: ${SECRET_PASSWORD}\n# or use an API token instead\n#       api-token: ${SDK_API_TOKEN}","handlingStrategy":"validation","validationCode":"// In config validation at startup\nboolean hasUser = !isBlank(cfg.username);\nboolean hasPass = !isBlank(cfg.password);\nboolean hasToken = !isBlank(cfg.apiToken);\nif ((hasUser ^ hasPass) && !hasToken) {\n    throw new IllegalArgumentException(\n        \"Configure both username and password, or use api-token, for kestra.tasks.sdk.authentication\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set username AND password together, or use api-token alone.","Source secrets from the same vault/env source so one is never missing.","Add a config linter that flags half-set auth pairs before deploy."],"tags":["configuration","authentication","sdk","startup","security"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}