{"record":{"id":"1b645dd68e9efaf9","repo":"apache/seatunnel","slug":"transport-aes-secret-key-base64-is-required-when-t","errorCode":null,"errorMessage":"transport.aes-secret-key-base64 is required when transport.encryption is \"aes_gcm\".","messagePattern":"transport\\.aes-secret-key-base64 is required when transport\\.encryption is \"aes_gcm\"\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-edge-agent/seatunnel-edge-agent-transport/src/main/java/org/apache/seatunnel/edge/agent/transport/config/EdgeTransportConfig.java","lineNumber":71,"sourceCode":"        this.endpoint = trimmedEndpoint;\n\n        String authType = config.get(EdgeTransportOptions.AUTH_TYPE);\n        validateAuthType(authType);\n        String rawToken = config.getOptional(EdgeTransportOptions.TOKEN).orElse(null);\n        if (rawToken == null || rawToken.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"transport.token is required.\");\n        }\n        this.token = rawToken.trim();\n\n        EdgePacketMode.from(config.get(EdgeTransportOptions.PACKET_MODE));\n        EdgePacketCompressionType.from(config.get(EdgeTransportOptions.COMPRESSION));\n        EdgePacketEncryptionType encryption =\n                EdgePacketEncryptionType.from(config.get(EdgeTransportOptions.ENCRYPTION));\n        if (encryption == EdgePacketEncryptionType.AES_GCM) {\n            String key =\n                    config.getOptional(EdgeTransportOptions.AES_SECRET_KEY_BASE64).orElse(null);\n            if (key == null || key.trim().isEmpty()) {\n                throw new IllegalArgumentException(\n                        \"transport.aes-secret-key-base64 is required when transport.encryption\"\n                                + \" is \\\"aes_gcm\\\".\");\n            }\n        }\n\n        this.connectTimeoutMs = config.get(EdgeTransportOptions.CONNECT_TIMEOUT_MS);\n        this.readTimeoutMs = config.get(EdgeTransportOptions.READ_TIMEOUT_MS);\n        this.maxBatchSendAttempts = config.get(EdgeTransportOptions.MAX_BATCH_SEND_ATTEMPTS);\n        this.initialBackoffMs = config.get(EdgeTransportOptions.INITIAL_BACKOFF_MS);\n        this.maxBackoffMs = config.get(EdgeTransportOptions.MAX_BACKOFF_MS);\n        this.maxReconnectCycles = config.get(EdgeTransportOptions.MAX_RECONNECT_CYCLES);\n    }\n\n    public static EdgeTransportConfig from(ReadonlyConfig config) {\n        return new EdgeTransportConfig(config);\n    }\n\n    public static long computeBackoffMillis(long attempt, long initial, long max) {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-edge-agent/seatunnel-edge-agent-transport/src/main/java/org/apache/seatunnel/edge/agent/transport/config/EdgeTransportConfig.java#L53-L89","documentation":"EdgeTransportConfig validates the transport configuration at startup. When transport.encryption is set to \"aes_gcm\", packets are encrypted with AES-GCM, which requires a shared secret; the code reads transport.aes-secret-key-base64 and throws IllegalArgumentException if it is absent or blank. This fail-fast check prevents starting a transport that could not encrypt traffic.","triggerScenarios":"Constructing EdgeTransportConfig (from a Config) with EdgeTransportOptions.ENCRYPTION resolved to AES_GCM while config.getOptional(EdgeTransportOptions.AES_SECRET_KEY_BASE64) returns empty or a whitespace-only string.","commonSituations":"User sets transport.encryption = \"aes_gcm\" in the agent HOCON file but forgets the key entry; the key is supplied via an env var that is not exported; a copy-pasted key consisting of only spaces; upgrading from \"none\" encryption to \"aes_gcm\" without adding the new option.","solutions":["Set transport.aes-secret-key-base64 in the agent config to a Base64-encoded 128/192/256-bit key (e.g. generate with `openssl rand -base64 32`).","If encryption is not needed, change transport.encryption to \"none\" (or remove it) so the key is not required.","If the key is injected via environment placeholder, verify the variable is actually set in the agent's runtime environment.","Confirm there are no typos in the option name transport.aes-secret-key-base64 and that the key is in the config file actually loaded."],"exampleFix":"// before\ntransport {\n  encryption = \"aes_gcm\"\n}\n\n// after\ntransport {\n  encryption = \"aes_gcm\"\n  aes-secret-key-base64 = \"bXktMzItYnl0ZS1zZWNyZXQta2V5LTEyMzQ1Njc4\"\n}","handlingStrategy":"validation","validationCode":"Config cfg = ConfigProvider.getConfig();\nString encryption = cfg.hasPath(\"transport.encryption\") ? cfg.getString(\"transport.encryption\") : \"none\";\nif (\"aes_gcm\".equalsIgnoreCase(encryption)\n        && (!cfg.hasPath(\"transport.aes-secret-key-base64\")\n            || cfg.getString(\"transport.aes-secret-key-base64\").trim().isEmpty())) {\n    throw new IllegalStateException(\"transport.aes-secret-key-base64 must be set when transport.encryption=aes_gcm\");\n}","typeGuard":"boolean hasAesKey(Config cfg) {\n    return !\"aes_gcm\".equalsIgnoreCase(cfg.getString(\"transport.encryption\"))\n        || cfg.hasPath(\"transport.aes-secret-key-base64\")\n            && !cfg.getString(\"transport.aes-secret-key-base64\").trim().isEmpty();\n}","tryCatchPattern":"try {\n    EdgeTransportConfig transportConfig = new EdgeTransportConfig(config);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"aes-secret-key-base64\")) {\n        LOG.error(\"Transport encryption requires a Base64 AES key; fix config and restart\", e);\n    }\n    throw e;\n}","preventionTips":["Generate and store the Base64 key once (openssl rand -base64 32) and reference it via a templated config.","Keep encryption mode and key in the same config template so they are added/removed together.","Run a config dry-run validation step in CI before deploying agent configs.","Never hand-edit encryption mode without checking the dependent key options."],"tags":["config","encryption","validation","startup"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}