{"record":{"id":"3a6ca544082fbb1c","repo":"testcontainers/testcontainers-java","slug":"cannot-create-service-account-token-in-external-mode","errorCode":null,"errorMessage":"Cannot create service account token in external mode","messagePattern":"Cannot create service account token in external mode","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java","lineNumber":533,"sourceCode":"        }\n    }\n\n    private static void ensureCompatibleVersion(String esVersion) {\n        ComparableVersion comparableVersion = new ComparableVersion(esVersion);\n        if (comparableVersion.isLessThan(MINIMUM_SUPPORTED_VERSION)) {\n            throw new IllegalArgumentException(\n                String.format(\n                    \"Kibana version %s is not supported. Minimum version is %s\",\n                    comparableVersion,\n                    MINIMUM_SUPPORTED_VERSION\n                )\n            );\n        }\n    }\n\n    private String createKibanaServiceAccountToken(String protocol) {\n        if (elasticsearch == null) {\n            throw new IllegalStateException(\"Cannot create service account token in external mode\");\n        }\n\n        String elasticPassword = elasticsearch\n            .getEnvMap()\n            .getOrDefault(\"ELASTIC_PASSWORD\", ElasticsearchContainer.ELASTICSEARCH_DEFAULT_PASSWORD);\n\n        // Create a unique token name to avoid collisions if the same ES container is reused.\n        String tokenName = \"tc-kibana-\" + Base58.randomString(12);\n\n        String endpoint = protocol + \"://localhost:9200/_security/service/elastic/kibana/credential/token/\" + tokenName;\n\n        return Unreliables.retryUntilSuccess(\n            45,\n            TimeUnit.SECONDS,\n            () -> {\n                String curlTlsArgs = \"\";\n                if (\"https\".equals(protocol)) {\n                    // In managed HTTPS mode, use the Elasticsearch HTTP CA for curl.","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java#L515-L551","documentation":"createKibanaServiceAccountToken runs the elasticsearch-service-tokens tool inside the managed Elasticsearch container, so it requires a managed (non-null) ElasticsearchContainer reference. In external mode — when KibanaContainer is constructed only with an image and points at an already-running ES — there is no container to exec into, so the library throws this IllegalStateException instead of returning a bogus token.","triggerScenarios":"Calling kibana.token() on a KibanaContainer created in external mode (no ElasticsearchContainer passed / elasticsearch == null), e.g. new KibanaContainer(image).withEnv(\"ELASTICSEARCH_HOSTS\", ...) pointing at an external cluster.","commonSituations":"Copy-pasting managed-mode sample code (which calls token()) into a test that connects to an external/self-hosted Elasticsearch; switching a test from managed to external mode but leaving the token() call in place.","solutions":["Remove the token() call in external mode; instead supply credentials for the external cluster yourself (e.g. generate the service token out-of-band and pass it via withEnv).","Switch to managed mode by constructing KibanaContainer with a started ElasticsearchContainer if you need the library to mint tokens.","Guard the call: only invoke token() when kibana was built in managed mode."],"exampleFix":"// before\nKibanaContainer kibana = new KibanaContainer(image); // external mode\nString token = kibana.token(); // throws\n\n// after\n// external mode: provide config without token()\nkibana.withEnv(\"ELASTICSEARCH_SERVICEACCOUNTTOKEN\", System.getenv(\"MY_KIBANA_TOKEN\"));","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// only fetch tokens in managed mode\nboolean isManagedMode(KibanaContainer kibana) {\n    // track how you built it\n    return kibanaManagedFlag; // set true when constructed with an ElasticsearchContainer\n}\nif (!isManagedMode(kibana)) return externalTokenFromEnv();","tryCatchPattern":null,"preventionTips":["Document per test class whether Kibana is managed or external and gate token() calls accordingly.","In external mode, provision service tokens out-of-band and inject them via withEnv.","Keep managed and external test fixtures in separate base classes."],"tags":["testcontainers","kibana","elasticsearch","service-account","external-mode"],"backgroundTag":"unsupported-operation","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}