{"record":{"id":"e4895dac3bc23d78","repo":"apache/druid","slug":"cannot-create-tempdir-s-for-google-storage-conn","errorCode":null,"errorMessage":"Cannot create tempDir [%s] for google storage connector","messagePattern":"Cannot create tempDir \\[(.+?)\\] for google storage connector","errorType":"exception","errorClass":"RE","httpStatus":null,"severity":"critical","filePath":"extensions-core/google-extensions/src/main/java/org/apache/druid/storage/google/output/GoogleStorageConnector.java","lineNumber":74,"sourceCode":"\n  public GoogleStorageConnector(\n      GoogleOutputConfig config,\n      GoogleStorage googleStorage,\n      GoogleInputDataConfig inputDataConfig\n  )\n  {\n    this.storage = googleStorage;\n    this.config = config;\n    this.inputDataConfig = inputDataConfig;\n\n    Preconditions.checkNotNull(config, \"config is null\");\n    Preconditions.checkNotNull(config.getTempDir(), \"tempDir is null in google config\");\n\n    try {\n      FileUtils.mkdirp(config.getTempDir());\n    }\n    catch (IOException e) {\n      throw new RE(\n          e,\n          StringUtils.format(\"Cannot create tempDir [%s] for google storage connector\", config.getTempDir())\n      );\n    }\n  }\n\n  @Override\n  public boolean pathExists(String path)\n  {\n    return storage.exists(config.getBucket(), objectPath(path));\n  }\n\n  @Override\n  public OutputStream write(String path)\n  {\n    return storage.getObjectOutputStream(config.getBucket(), objectPath(path), config.getChunkSize().getBytesInInt());\n  }\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/google-extensions/src/main/java/org/apache/druid/storage/google/output/GoogleStorageConnector.java#L56-L92","documentation":"GoogleStorageConnector's constructor requires a local scratch tempDir (from GoogleStorageDruidModule config) and calls FileUtils.mkdirp to create it. If creation fails (permissions, existing non-directory file, read-only FS), the constructor throws this RuntimeException, so the connector (and any job using it) cannot start.","triggerScenarios":"Constructing GoogleStorageConnector when config.getTempDir() cannot be created: parent dir not writable, path exists as a regular file, disk full, or container running as non-root on a read-only filesystem.","commonSituations":"Kubernetes containers with read-only root filesystems and default druid/tmp paths; running Druid as an unprivileged user after another user created the dir; docker-compose configs without volume mounts for the temp dir.","solutions":["Set druid.google.output.tempDir (google config tempDir) to a writable path, e.g. a mounted volume like /opt/druid/var/tmp or /tmp.","Pre-create the directory manually with correct ownership: mkdir -p <dir> && chown druid:druid <dir>.","If the path exists as a file, remove it first.","For containers, mount an emptyDir/PV at the tempDir path and avoid read-only rootfs.","Run the process as a user that owns the configured directory."],"exampleFix":"// before\ndruid.storage.google.tempDir=/var/druid/shared-tmp   // not writable in container\n// after\ndruid.storage.google.tempDir=/tmp/google-connector-tmp\n// (or mount a writable volume at the configured path)","handlingStrategy":"validation","validationCode":"File tmp = config.getTempDir();\nif (tmp.exists() && !tmp.isDirectory()) {\n  throw new IllegalStateException(\"tempDir exists but is not a directory: \" + tmp);\n}\nif (!tmp.canWrite() && !tmp.mkdirs() && !tmp.isDirectory()) {\n  throw new IllegalStateException(\"tempDir not writable/creatable: \" + tmp);\n}","typeGuard":null,"tryCatchPattern":"try { new GoogleStorageConnector(fs, config); }\ncatch (RE e) { alert(\"Fix druid.storage.google tempDir: \" + e.getMessage()); }","preventionTips":["Configure a guaranteed-writable tempDir (mounted volume) before deploying.","Pre-create and chown the directory in the container image/entrypoint.","Avoid read-only root filesystems without an explicit writable mount.","Verify writability as the same user Druid runs as."],"tags":["filesystem","mkdir","permissions","gcs-connector"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}