Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Gzipped tar upload to /api/v2/files causes nil pointer panic in preview, reported as "Unable to parse workspace tags" #28913

Description

@moe2566

What happened

POST /api/v2/files accepts and stores a gzipped tar without error, returning a valid hash. Any later use of that file — e.g. POST /api/v2/organizations/{org}/templateversions — panics:

{
  "message": "Unable to parse workspace tags",
  "detail": "Panic occurred in preview. This should not happen, please report this to Coder.; panic in preview: runtime error: invalid memory address or nil pointer dereference"
}

The message points at workspace tag parsing, which is misleading — the tag step appears to be simply the first consumer of the filesystem. The actual cause is the archive, uploaded several steps earlier.

Reproduction

mkdir t && printf 'terraform { required_providers { coder = { source = "coder/coder" } } }\n' > t/main.tf

# gzipped — the mistake
tar czf t.tar.gz -C t .

FID=$(curl -s -X POST -H "Coder-Session-Token: $TOKEN" \
  -H "Content-Type: application/x-tar" --data-binary @t.tar.gz \
  "$CODER_URL/api/v2/files" | jq -r .hash)

# succeeds and returns a hash

curl -s -X POST -H "Coder-Session-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"storage_method\":\"file\",\"file_id\":\"$FID\",\"provisioner\":\"terraform\",\"message\":\"x\"}" \
  "$CODER_URL/api/v2/organizations/$ORG/templateversions"

# panics

An empty template panics too — the template content is never reached.

Replacing tar czf with tar cf fixes it completely.

Why it's confusing in practice

  • The upload succeeds and returns a hash, so the archive looks accepted.
  • The error names workspace tags, which has nothing to do with the cause.
  • It reproduces on an empty template, which rules out the template and sends you looking at permissions, tokens, and Terraform instead.
  • coder templates push works on the same server with the same template, so the CLI and the API disagree in a way I could not find documented.

I spent a while ruling out permissions (an owner token fails identically to a template-admin service account) and template content before finding it.

Suggested fixes

I have not read the source directly, so treat the pointers below as a starting point rather than a diagnosis:

  1. Reject unparseable archives at upload. The handler for /api/v2/files appears to validate only the Content-Type header without reading the archive. Validating there would turn this into a clean 400 at the point of the mistake, rather than a panic much later.
  2. Guard the tar reader. The panic looks like a nil filesystem being returned when the tar cannot be read, then dereferenced by its first caller.
  3. Optionally accept gzip, or document that only application/x-tar and application/zip are supported — the asymmetry with the CLI is the part that cost me the most time.

Environment

  • Coder v2.36.1+9548f23 (ghcr.io/coder/coder:latest)
  • Docker Compose, Postgres 18
  • terraform-provider-coder v2.18.0
  • Reproduced on :latest as of 2026-09-02

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions