{"record":{"id":"df7223b7131d7e98","repo":"apache/seatunnel","slug":"the-gcs-service-account-key-file-option-must-not-b","errorCode":null,"errorMessage":"The GCS service_account_key_file option must not be blank","messagePattern":"The GCS service_account_key_file option must not be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-gcs/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/gcs/config/GcsHadoopConf.java","lineNumber":100,"sourceCode":"                throw invalidBucket(bucket);\n            }\n        } catch (URISyntaxException e) {\n            throw invalidBucket(bucket);\n        }\n    }\n\n    private static IllegalArgumentException invalidBucket(String bucket) {\n        return new IllegalArgumentException(\n                String.format(\n                        \"The GCS bucket must be a bucket URI such as 'gs://my-bucket', but was '%s'. \"\n                                + \"Configure object paths with the 'path' option.\",\n                        bucket));\n    }\n\n    private static void configureServiceAccount(\n            Map<String, String> properties, String serviceAccountKeyFile) {\n        if (StringUtils.isBlank(serviceAccountKeyFile)) {\n            throw new IllegalArgumentException(\n                    \"The GCS service_account_key_file option must not be blank\");\n        }\n        properties.put(GCS_SERVICE_ACCOUNT_KEY_FILE, serviceAccountKeyFile);\n    }\n}\n","sourceCodeStart":82,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-gcs/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/gcs/config/GcsHadoopConf.java#L82-L106","documentation":"GcsHadoopConf.configureServiceAccount translates the user option service_account_key_file into a Hadoop property for the GCS connector. If the value is blank (null/empty/whitespace) — meaning the option was declared but not given a usable value — it throws IllegalArgumentException since GCS auth cannot proceed without a key file path.","triggerScenarios":"buildWithReadonlyConfig → configureServiceAccount called with serviceAccountKeyFile blank: the config contains service_account_key_file as an empty string or the option resolves to empty/whitespace.","commonSituations":"Config file has `service_account_key_file = \"\"` or a placeholder that an env-var substitution left empty; user forgot to set the key path while service account auth is expected; variable interpolation failure in the deployment pipeline (secret not injected).","solutions":["Set service_account_key_file to a valid, absolute path to the service account JSON key file, e.g. service_account_key_file = \"/path/to/key.json\"","If the value comes from an env var/secret manager, verify it was actually injected at runtime (echo the resolved config)","If you intended default/ADC credentials instead, remove the empty option rather than passing a blank value"],"exampleFix":"// before\nGcsFile {\n    service_account_key_file = \"\"\n}\n// after\nGcsFile {\n    service_account_key_file = \"/etc/secrets/gcs-service-account.json\"\n}","handlingStrategy":"validation","validationCode":"// Java: validate key file before building config\nString keyFile = config.get(\"service_account_key_file\");\nif (keyFile == null || keyFile.isBlank()) {\n    throw new IllegalArgumentException(\"service_account_key_file must be set to a non-blank JSON key path\");\n}\nif (!java.nio.file.Files.isReadable(java.nio.file.Path.of(keyFile))) {\n    throw new IllegalArgumentException(\"service account key not readable: \" + keyFile);\n}","typeGuard":"// Java\nstatic boolean hasServiceAccountKey(Map<String,String> cfg) {\n    String v = cfg.get(\"service_account_key_file\");\n    return v != null && !v.isBlank();\n}","tryCatchPattern":"try {\n    factory.createSink(...);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"service_account_key_file\")) {\n        logger.error(\"Set service_account_key_file to a valid JSON key path\");\n    }\n    throw e;\n}","preventionTips":["Never leave service_account_key_file as an empty string; omit it if using ADC","Verify secret-manager/env interpolation actually resolves the key path","Check the key file exists and is readable by the job user at runtime"],"tags":["gcs","config","authentication"],"backgroundTag":"empty-required-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"}