{"record":{"id":"4caf7215b8ae9260","repo":"pulumi/pulumi","slug":"signed-urls-not-supported-with-postgresql-backend","errorCode":null,"errorMessage":"signed URLs not supported with PostgreSQL backend","messagePattern":"signed URLs not supported with PostgreSQL backend","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/backend/diy/postgres/bucket.go","lineNumber":426,"sourceCode":"\n\trowsAffected, err := result.RowsAffected()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif rowsAffected == 0 {\n\t\treturn fmt.Errorf(\"key not found: %s\", key)\n\t}\n\n\treturn nil\n}\n\n// SignedURL implements driver.Bucket.SignedURL.\nfunc (d *postgresBucketDriver) SignedURL(\n\tctx context.Context, key string, opts *driver.SignedURLOptions,\n) (string, error) {\n\t// PostgreSQL doesn't support pre-signed URLs\n\treturn \"\", errors.New(\"signed URLs not supported with PostgreSQL backend\")\n}\n\n// Close implements driver.Bucket.Close.\nfunc (d *postgresBucketDriver) Close() error {\n\treturn nil\n}\n\n// postgresReader implements driver.Reader for PostgreSQL.\ntype postgresReader struct {\n\tr        io.ReadSeeker\n\tsize     int64\n\tmodTime  time.Time\n\tmetadata map[string]string\n}\n\n// Read implements io.Reader.\nfunc (r *postgresReader) Read(p []byte) (int, error) {\n\treturn r.r.Read(p)","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/backend/diy/postgres/bucket.go#L408-L444","documentation":"SignedURL is intentionally unimplemented for the PostgreSQL blob backend: postgres has no concept of pre-signed URLs like S3/GCS/Azure. Calling it always returns this fixed error. Code paths that rely on obtaining a temporary download/upload URL (some backends and tooling use SignedURL for direct object access) cannot work with the DIY postgres bucket.","triggerScenarios":"Any code path invoking SignedURL on a bucket backed by pkg/backend/diy/postgres — e.g. features or scripts that fetch pre-signed links to state objects, or switching a workflow from an S3/GCS backend to postgres while retaining signed-URL usage.","commonSituations":"Migrating from an S3-style backend to the postgres DIY backend and expecting pre-signed URLs to still work; custom tooling generating download links for state files; tests comparing backend capabilities.","solutions":["Use direct database access (SELECT data) or the normal blob read API instead of signed URLs for postgres-backed state","Keep using a cloud object-store backend (S3/GCS/Azure) if pre-signed URLs are a hard requirement","Implement application-level authorized access in front of the DB (your own endpoint issuing tokens) rather than pre-signed URLs"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// capability check before relying on signed URLs\nif backend is postgres/DIY {\n    // use direct read path instead of SignedURL\n}","typeGuard":null,"tryCatchPattern":"url, err := bucket.SignedURL(ctx, key, opts)\nif err != nil && strings.Contains(err.Error(), \"not supported\") {\n    // fallback: read object directly via bucket API\n    r, rerr := bucket.NewReader(ctx, key, nil)\n    // serve bytes through your own authenticated endpoint\n}","preventionTips":["Detect backend type up front and skip signed-URL features for DIY/postgres","Route downloads through your own auth layer when using postgres state","Keep S3/GCS/Azure backends if pre-signed URLs are required","Document backend capability differences in team tooling"],"tags":["postgres","signed-url","unsupported-feature","blob-storage"],"backgroundTag":"feature-not-supported","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}