{"record":{"id":"8def5b235f187b80","repo":"apache/beam","slug":"provided-secret-must-be-in-the-form-projects-project-secrets","errorCode":null,"errorMessage":"Provided Secret must be in the form projects/{project}/secrets/{secret}/versions/{secret_version}","messagePattern":"Provided Secret must be in the form projects/(.+?)/secrets/(.+?)/versions/(.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/kafka-factories/src/main/java/org/apache/beam/sdk/extensions/kafka/factories/FileAwareFactoryFn.java","lineNumber":243,"sourceCode":"   * handled. For example, the kerberos factory can use this to download a krb5.conf and set a\n   * system property.\n   *\n   * @throws IOException If downloading or processing the file fails.\n   */\n  protected void downloadAndProcessExtraFiles() throws IOException {\n    // Default implementation should do nothing.\n  }\n\n  protected String getBaseDirectory() {\n    return DIRECTORY_PREFIX;\n  }\n\n  protected byte[] getSecret(String secretVersion) {\n    SecretVersionName secretVersionName;\n    if (SecretVersionName.isParsableFrom(secretVersion)) {\n      secretVersionName = SecretVersionName.parse(secretVersion);\n    } else {\n      throw new IllegalArgumentException(\n          \"Provided Secret must be in the form\"\n              + \" projects/{project}/secrets/{secret}/versions/{secret_version}\");\n    }\n    try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {\n      AccessSecretVersionResponse response = client.accessSecretVersion(secretVersionName);\n      return response.getPayload().getData().toByteArray();\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  protected String processSecret(String originalValue, String secretId, byte[] secretValue) {\n    // By Default, this will return the secret value directly. This function can be overridden by\n    // derived classes.\n    return new String(secretValue, StandardCharsets.UTF_8);\n  }\n}\n","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/kafka-factories/src/main/java/org/apache/beam/sdk/extensions/kafka/factories/FileAwareFactoryFn.java#L225-L261","documentation":"getSecret() accepts a Secret Manager resource name and validates it with SecretVersionName.isParsableFrom() before calling the Secret Manager API. If the string doesn't match projects/{project}/secrets/{secret}/versions/{version}, an IllegalArgumentException with the required format is thrown. It guards against malformed resource names hitting the GCP API.","triggerScenarios":"A sasl.jaas.config keytab reference or other secret key contains a value like \"my-secret\" or \"projects/p/secrets/s\" (missing the versions segment) instead of the full 4-part SecretVersionName.","commonSituations":"Users pasting the secret ID instead of the full version resource name; omitting \"versions/latest\"; templating that dropped part of the path; mixing Secret Manager secret names with version names.","solutions":["Use the fully qualified form: projects/PROJECT/secrets/SECRET/versions/VERSION (e.g. versions/latest)","Validate the string with SecretVersionName.isParsableFrom(value) before configuring","Build the name programmatically with SecretVersionName.of(project, secret, version).toString()","Verify no whitespace or quotes leaked in from property files around the resource name"],"exampleFix":"// before\nString secret = \"projects/my-proj/secrets/kafka-keytab\";\n// after\nString secret = \"projects/my-proj/secrets/kafka-keytab/versions/latest\";","handlingStrategy":"validation","validationCode":"java\nString SECRET_RE = \"^projects/[^/]+/secrets/[^/]+/versions/[^/]+$\";\nif (!secretVersion.matches(SECRET_RE)) {\n  throw new IllegalArgumentException(\"Bad secret version name: \" + secretVersion);\n}","typeGuard":null,"tryCatchPattern":"java\ntry {\n  byte[] keytab = factoryFn.getSecret(secret);\n} catch (IllegalArgumentException e) {\n  log.severe(\"Secret reference malformed: \" + e.getMessage());\n}","preventionTips":["Use SecretVersionName.of(project, secret, version).toString() to build names","Always include a versions segment (commonly versions/latest)","Trim whitespace/quotes from config values before use","Validate with SecretVersionName.isParsableFrom in config checks"],"tags":["java","gcp","secret-manager","configuration"],"backgroundTag":"invalid-identifier-format","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}