{"record":{"id":"b915d3635a7c4183","repo":"thephpleague/flysystem","slug":"unable-to-get-checksum-for-path-reason-b915d3","errorCode":null,"errorMessage":"Unable to get checksum for $path: $reason","messagePattern":"Unable to get checksum for \\$path: \\$reason","errorType":"exception","errorClass":"UnableToProvideChecksum","httpStatus":null,"severity":"error","filePath":"src/GoogleCloudStorage/GoogleCloudStorageAdapter.php","lineNumber":392,"sourceCode":"        }\n    }\n\n    public function checksum(string $path, Config $config): string\n    {\n        $algo = $config->get('checksum_algo', 'md5');\n        $header = static::$algoToInfoMap[$algo] ?? null;\n\n        if ($header === null) {\n            throw new ChecksumAlgoIsNotSupported();\n        }\n\n        $prefixedPath = $this->prefixer->prefixPath($path);\n\n        try {\n            $checksum = $this->bucket->object($prefixedPath)->info()[$header]\n                ?? throw new LogicException(\"Header not present: $header\");\n        } catch (Throwable $exception) {\n            throw new UnableToProvideChecksum($exception->getMessage(), $path);\n        }\n\n        return bin2hex(base64_decode($checksum));\n    }\n\n    public function temporaryUrl(string $path, DateTimeInterface $expiresAt, Config $config): string\n    {\n        $location = $this->prefixer->prefixPath($path);\n\n        try {\n            return $this->bucket->object($location)->signedUrl($expiresAt, $config->get('gcp_signing_options', []));\n        } catch (Throwable $exception) {\n            throw UnableToGenerateTemporaryUrl::dueToError($path, $exception);\n        }\n    }\n}\n","sourceCodeStart":374,"sourceCodeEnd":409,"githubUrl":"https://github.com/thephpleague/flysystem/blob/b277b5dc3d56650b68904117124e79c851e12376/src/GoogleCloudStorage/GoogleCloudStorageAdapter.php#L374-L409","documentation":"GoogleCloudStorageAdapter::checksum() fetches the object's metadata ($this->bucket->object($path)->info()) and reads the field matching the algorithm (md5Hash, crc32c, or etag). Two failure modes land in the same catch: the Google API call itself fails (404 for missing object, auth, network), or the info array lacks the header, raising LogicException('Header not present: ...'). Both are wrapped as UnableToProvideChecksum with the underlying message.","triggerScenarios":"Checksumming a nonexistent object (storage.objects.get returns 404); service-account credentials without storage.objects.get on the bucket; requesting 'md5' on a composite object, whose md5Hash is absent (only crc32c is defined for composites); transient API errors.","commonSituations":"Composite objects created by gsutil compose or GCS compose() calls; path/prefix mistakes through PathPrefixedAdapter; IAM roles missing object reader; verifying objects right after upload with eventual metadata visibility.","solutions":["Confirm the object exists with fileExists() and inspect the wrapped message for 'Header not present: md5Hash' vs an API 404.","For composite objects, request 'crc32c' instead of 'md5'.","Grant the service account roles/storage.objectViewer (and storage.objects.get) on the bucket.","Catch UnableToProvideChecksum and branch on the message/previous exception to retry transient API failures."],"exampleFix":"// before\n$checksum = $adapter->checksum('composed/merged.dat', new Config(['checksum_algo' => 'md5'])); // composite object -> 'Header not present: md5Hash'\n\n// after\n$checksum = $adapter->checksum('composed/merged.dat', new Config(['checksum_algo' => 'crc32c'])); // defined for composites","handlingStrategy":"try-catch","validationCode":"if ( ! $filesystem->fileExists($path)) {\n    throw new DomainException(\"Object missing, cannot checksum: {$path}\");\n}\n// Composite objects lack md5Hash — request crc32c for anything under a compose() prefix\n$algo = str_starts_with($path, 'composed/') ? 'crc32c' : 'md5';","typeGuard":null,"tryCatchPattern":"use League\\Flysystem\\UnableToProvideChecksum;\n\ntry {\n    $checksum = $filesystem->checksum($path, ['checksum_algo' => 'md5']);\n} catch (UnableToProvideChecksum $e) {\n    if (str_contains($e->getMessage(), 'Header not present: md5Hash')) {\n        // composite object: crc32c is always defined\n        return $filesystem->checksum($path, ['checksum_algo' => 'crc32c']);\n    }\n    // otherwise: 404/auth/network — inspect and handle accordingly\n    throw $e;\n}","preventionTips":["Prefer crc32c when your dataset includes composite objects — it is defined for all GCS objects.","Ensure the service account has storage.objects.get on the bucket before checksum workflows.","Track which prefixes hold composites and choose the algorithm accordingly in config."],"tags":["php","flysystem","google-cloud-storage","checksum","composite-object","not-found","iam"],"backgroundTag":"checksum-retrieval-failed","analyzedSha":"b277b5dc3d56650b68904117124e79c851e12376","analyzedAt":"2026-08-17T04:28:35.741Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}