{"record":{"id":"692f7c6ffe43f3c7","repo":"quarkusio/quarkus","slug":"you-must-provide-either-a-valid-username-password","errorCode":null,"errorMessage":"You must provide either a valid username/password pair for Basic authentication OR only a valid API key for ApiKey authentication. Both methods are currently enabled.","messagePattern":"You must provide either a valid username/password pair for Basic authentication OR only a valid API key for ApiKey authentication\\. Both methods are currently enabled\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"extensions/elasticsearch-rest-client/runtime/src/main/java/io/quarkus/elasticsearch/restclient/lowlevel/runtime/RestClientBuilderHelper.java","lineNumber":131,"sourceCode":"                .setSniffIntervalMillis((int) config.discovery().refreshInterval().toMillis());\n\n        // https discovery support\n        if (\"https\".equalsIgnoreCase(config.protocol())) {\n            NodesSniffer hostsSniffer = new ElasticsearchNodesSniffer(\n                    client,\n                    ElasticsearchNodesSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT, // 1sec\n                    ElasticsearchNodesSniffer.Scheme.HTTPS);\n            builder.setNodesSniffer(hostsSniffer);\n        }\n\n        return builder.build();\n    }\n\n    private static void applyAuthentication(HttpAsyncClientBuilder httpClientBuilder, ElasticsearchConfig config) {\n        boolean hasBasic = config.username().isPresent();\n        boolean hasApiKey = config.apiKey().isPresent();\n        if (hasBasic && hasApiKey) {\n            throw new ConfigurationException(\"You must provide either a valid username/password pair for Basic \" +\n                    \"authentication OR only a valid API key for ApiKey authentication. Both methods are currently \" +\n                    \"enabled.\");\n        }\n        if (!\"https\".equalsIgnoreCase(config.protocol()) && (hasBasic || hasApiKey)) {\n            LOG.warn(\"Transmitting authentication information over HTTP is unsafe as it implies sending sensitive \" +\n                    \"information as plain text over an unencrypted channel. Use the HTTPS protocol instead.\");\n        }\n        if (hasBasic) {\n            BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n            credentialsProvider.setCredentials(\n                    new AuthScope(null, null, -1, null, null),\n                    new UsernamePasswordCredentials(config.username().get(), config.password()\n                            .map(String::toCharArray).orElse(null)));\n            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n        } else if (hasApiKey) {\n            String apiKey = config.apiKey().get();\n            Header apiKeyHeader = new BasicHeader(HttpHeaders.AUTHORIZATION, \"ApiKey \" + apiKey);\n            httpClientBuilder.setDefaultHeaders(Collections.singleton(apiKeyHeader));","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/elasticsearch-rest-client/runtime/src/main/java/io/quarkus/elasticsearch/restclient/lowlevel/runtime/RestClientBuilderHelper.java#L113-L149","documentation":"RestClientBuilderHelper.applyAuthentication() rejects configurations that enable both Basic auth (username/password) and ApiKey auth simultaneously. The Elasticsearch low-level REST client builder supports only one authentication method, so a ConfigurationException is thrown when both quarkus.elasticsearch.username and quarkus.elasticsearch.api-key are present.","triggerScenarios":"Setting both quarkus.elasticsearch.username (and password) and quarkus.elasticsearch.api-key in application.properties; also stale config left behind when switching auth schemes.","commonSituations":"Migrating from Basic to API-key auth without removing username/password; copying config snippets from different environments; CI secrets injecting both variables.","solutions":["Remove quarkus.elasticsearch.username/password and keep only quarkus.elasticsearch.api-key","Or remove quarkus.elasticsearch.api-key and keep username/password","Audit env vars/CI secrets (ELASTICSEARCH_USERNAME, ELASTICSEARCH_API_KEY) so only one scheme is set"],"exampleFix":"// before\nquarkus.elasticsearch.username=elastic\nquarkus.elasticsearch.password=secret\nquarkus.elasticsearch.api-key=abc123\n// after\nquarkus.elasticsearch.api-key=abc123","handlingStrategy":"validation","validationCode":"String user = System.getProperty(\"quarkus.elasticsearch.username\", System.getenv(\"QUARKUS_ELASTICSEARCH_USERNAME\"));\nString key = System.getProperty(\"quarkus.elasticsearch.api-key\", System.getenv(\"QUARKUS_ELASTICSEARCH_API_KEY\"));\nif (user != null && key != null) throw new IllegalStateException(\"Set only one of username/password or api-key\");","typeGuard":null,"tryCatchPattern":"try { startApp(); }\ncatch (ConfigurationException e) {\n  if (e.getMessage().contains(\"Basic\") && e.getMessage().contains(\"ApiKey\")) { /* fix application.properties */ }\n  else throw e;\n}","preventionTips":["Keep exactly one auth scheme in application.properties per environment","Audit CI/CD secrets for both ELASTICSEARCH_USERNAME and ELASTICSEARCH_API_KEY","When migrating auth schemes, delete the old keys"],"tags":["elasticsearch","configuration","authentication"],"backgroundTag":"conflicting-auth-config","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"}