apache/beam · error

invalid manifest location

Error message

invalid manifest location

What it means

NewStagingServer expects the manifest path to be a valid GCS object specifier (bucket/object). gcsx.ParseObject failing — wrong scheme, missing bucket, malformed path — causes this wrapped error. The staging server only supports manifests stored in GCS.

Solutions

  1. Pass a full GCS object path like gs://my-bucket/staging/manifest.json.
  2. Check the pipeline option supplying the staging location is set and correctly prefixed with gs://.
  3. Verify the path has both a bucket and a non-empty object path (parseObject requires '/').
  4. Use path.Join on the object portion if building the path programmatically.

Example fix

// before
server, err := gcsproxy.NewStagingServer("/tmp/staging/manifest.json")
// after
server, err := gcsproxy.NewStagingServer("gs://my-bucket/staging/manifest.json")
Defensive patterns

Strategy: validation

Validate before calling

func validGCSObjectPath(p string) bool {
	u, err := url.Parse(p)
	return err == nil && u.Scheme == "gs" && u.Host != "" && strings.TrimPrefix(u.Path, "/") != ""
}
// call before NewStagingServer

Try / catch

srv, err := gcsproxy.NewStagingServer(manifestPath)
if err != nil {
	if strings.Contains(err.Error(), "invalid manifest location") {
		return fmt.Errorf("--staging_location must be a gs://bucket/object path: %w", err)
	}
}

Prevention

When it happens

Trigger: Calling NewStagingServer(manifest) with a path that isn't of the form gs://bucket/path/to/object (e.g. a local path, a bare bucket name, or an unsupported scheme).

Common situations: Passing a local filesystem path where a GCS path is required; forgetting the gs:// prefix; using an s3:// or other cloud path; empty string from an unset pipeline option.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/9f403b62b5a6d245. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/artifact/gcsproxy/staging.go:54

// (GCS). It commits a single manifest and ignores the staging id.
type StagingServer struct {
	manifest     string
	bucket, root string
	blobs        map[string]staged // guarded by mu
	mu           sync.Mutex
}

type staged struct {
	object, hash string
}

// NewStagingServer creates a artifact staging server for the given manifest.
// It requires that the manifest is in GCS and will stage the supplied
// artifacts next to it.
func NewStagingServer(manifest string) (*StagingServer, error) {
	bucket, object, err := gcsx.ParseObject(manifest)
	if err != nil {
		return nil, errors.Wrap(err, "invalid manifest location")
	}
	root := path.Join(path.Dir(object), "blobs")

	return &StagingServer{
		manifest: object,
		bucket:   bucket,
		root:     root,
		blobs:    make(map[string]staged),
	}, nil
}

// CommitManifest commits the given artifact manifest to GCS.
func (s *StagingServer) CommitManifest(ctx context.Context, req *jobpb.CommitManifestRequest) (*jobpb.CommitManifestResponse, error) {
	manifest := req.GetManifest()

	s.mu.Lock()
	loc, err := matchLocations(manifest.GetArtifact(), s.blobs)
	if err != nil {

View on GitHub (pinned to 12126d8942)