{"record":{"id":"60c76577c5a67abb","repo":"apache/seatunnel","slug":"transport-token-is-required","errorCode":null,"errorMessage":"transport.token is required.","messagePattern":"transport\\.token is required\\.","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":59,"sourceCode":"    private final long initialBackoffMs;\n    private final long maxBackoffMs;\n    private final int maxReconnectCycles;\n\n    public EdgeTransportConfig(ReadonlyConfig config) {\n        Objects.requireNonNull(config, \"config\");\n        String rawEndpoint = config.get(EdgeTransportOptions.ENDPOINT);\n        if (rawEndpoint == null || rawEndpoint.trim().isEmpty()) {\n            throw new IllegalArgumentException(\"transport.endpoint is required.\");\n        }\n        String trimmedEndpoint = rawEndpoint.trim();\n        EdgeTransportEndpoints.validateFormat(trimmedEndpoint);\n        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);","sourceCodeStart":41,"sourceCodeEnd":77,"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#L41-L77","documentation":"EdgeTransportConfig requires a non-blank transport.token for authentication. After validating the auth type, the constructor reads the optional TOKEN option and throws this IllegalArgumentException if it is absent or whitespace-only, because the agent cannot authenticate without a token.","triggerScenarios":"Constructing new EdgeTransportConfig(config) where transport.token is missing, empty, or only whitespace in the ReadonlyConfig, regardless of the configured auth type.","commonSituations":"Deploying with a config template where the token placeholder was never replaced; secrets not injected into the container/environment; token key removed during config refactoring; blank token passed via an empty environment variable interpolation.","solutions":["Set transport.token in the agent config to the credential issued by the server, e.g. transport:\\n  token: <secret>.","Verify secret injection (env vars, mounted secret files) actually populated the token in the deployed config.","Check that template placeholders like ${TOKEN} are resolved and not left empty at deploy time.","Confirm the token is trimmed/non-blank — whitespace-only values are rejected the same as missing ones."],"exampleFix":"// before\ntransport:\n  endpoint: 10.0.0.5:9090\n  token: \"\"\n// after\ntransport:\n  endpoint: 10.0.0.5:9090\n  token: ${AGENT_TOKEN}","handlingStrategy":"validation","validationCode":"String tok = config.get(EdgeTransportOptions.TOKEN); if (tok == null || tok.trim().isEmpty()) { throw new IllegalArgumentException(\"transport.token must be set before building EdgeTransportConfig\"); }","typeGuard":"boolean hasToken(org.apache.seatunnel.shade.com.typesafe.config.ReadonlyConfig c) { return c.getOptional(EdgeTransportOptions.TOKEN).map(t -> !t.trim().isEmpty()).orElse(false); }","tryCatchPattern":"try { new EdgeTransportConfig(config); } catch (IllegalArgumentException e) { if (e.getMessage().equals(\"transport.token is required.\")) { log.error(\"transport.token missing or blank; check secret injection\"); } throw e; }","preventionTips":["Inject the token via secrets management, never hardcode it.","Verify placeholder resolution (${AGENT_TOKEN}) at deploy time.","Reject blank tokens in deployment validation scripts.","Rotate tokens without emptying the config key."],"tags":["config","transport","authentication","missing-field"],"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-14T11:17:12.474Z"}