pulumi/pulumi · warning
signed URLs not supported with PostgreSQL backend
Error message
signed URLs not supported with PostgreSQL backend
What it means
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.
Source
Thrown at pkg/backend/diy/postgres/bucket.go:426
rowsAffected, err := result.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return fmt.Errorf("key not found: %s", key)
}
return nil
}
// SignedURL implements driver.Bucket.SignedURL.
func (d *postgresBucketDriver) SignedURL(
ctx context.Context, key string, opts *driver.SignedURLOptions,
) (string, error) {
// PostgreSQL doesn't support pre-signed URLs
return "", errors.New("signed URLs not supported with PostgreSQL backend")
}
// Close implements driver.Bucket.Close.
func (d *postgresBucketDriver) Close() error {
return nil
}
// postgresReader implements driver.Reader for PostgreSQL.
type postgresReader struct {
r io.ReadSeeker
size int64
modTime time.Time
metadata map[string]string
}
// Read implements io.Reader.
func (r *postgresReader) Read(p []byte) (int, error) {
return r.r.Read(p)View on GitHub (pinned to 793f7b2e16)
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
Defensive patterns
Strategy: fallback
Validate before calling
// capability check before relying on signed URLs
if backend is postgres/DIY {
// use direct read path instead of SignedURL
} Try / catch
url, err := bucket.SignedURL(ctx, key, opts)
if err != nil && strings.Contains(err.Error(), "not supported") {
// fallback: read object directly via bucket API
r, rerr := bucket.NewReader(ctx, key, nil)
// serve bytes through your own authenticated endpoint
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to parse JSON data: %w
- invalid offset: %d, size: %d
- key not found: %s
- stack deployments not supported with diy backends
- github integration not supported with diy backends
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/4caf7215b8ae9260.
Report an issue: GitHub.