dutchcoders/transfer.sh · error
Could not decrypt file
Error message
Could not decrypt file
What it means
In linx-server's getHandler, the file being downloaded is stored encrypted at rest. When the request carries an X-Decrypt-Password header, attachDecryptionReader wraps the storage reader in a decryption stream; if that setup fails (e.g. the password header is present but decryption cannot be initialized), the server aborts with HTTP 500 'Could not decrypt file'.
Source
Thrown at server/handlers.go:1259
if strings.TrimSpace(contentType) == "" {
contentType = "text/plain; charset=utf-8"
}
} else {
disposition = "attachment"
}
remainingDownloads, remainingDays := metadata.remainingLimitHeaderValues()
w.Header().Set("Content-Disposition", fmt.Sprintf(`%s; filename="%s"`, disposition, filename))
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Cache-Control", "no-store")
w.Header().Set("X-Remaining-Downloads", remainingDownloads)
w.Header().Set("X-Remaining-Days", remainingDays)
password := r.Header.Get("X-Decrypt-Password")
reader, err = attachDecryptionReader(reader, password)
if err != nil {
http.Error(w, "Could not decrypt file", http.StatusInternalServerError)
return
}
if metadata.Encrypted && len(password) > 0 {
contentType = metadata.DecryptedContentType
contentLength = uint64(metadata.ContentLength)
}
w.Header().Set("Content-Type", contentType)
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10))
w.Header().Set("Vary", "Range, Referer, X-Decrypt-Password")
if rng != nil && rng.ContentRange() != "" {
w.WriteHeader(http.StatusPartialContent)
}
if disposition == "inline" && canContainsXSS(contentType) {
reader = io.NopCloser(bluemonday.UGCPolicy().SanitizeReader(reader))View on GitHub (pinned to c37bfd9579)
Solutions
- Verify the file was actually uploaded with encryption (metadata.Encrypted true) before sending X-Decrypt-Password
- Re-upload the file with the same password to regenerate a valid encrypted blob
- Check the storage backend for corruption/truncation of the stored file or its metadata
- Remove the X-Decrypt-Password header if the file does not need decryption
- Upgrade/align client and server versions so the encryption format matches
Example fix
// before curl -H 'X-Decrypt-Password: secret' https://linx/files/doc.pdf // after # only send the header for files uploaded with encryption curl https://linx/files/doc.pdf # unencrypted upload — no header
Defensive patterns
Strategy: validation
Validate before calling
// client side: only send the password header for encrypted uploads
const headers = meta.encrypted ? {'X-Decrypt-Password': password} : {}
fetch(url, {headers}) Type guard
function isEncrypted(meta) { return typeof meta === 'object' && meta !== null && meta.encrypted === true && typeof meta.contentLength === 'number'; } Try / catch
try {
const res = await fetch(url, {headers});
if (!res.ok) throw new Error(await res.text());
const blob = await res.blob();
} catch (err) {
if (String(err).includes('Could not decrypt file')) {
// re-fetch without password or re-upload encrypted
}
} Prevention
- Only attach X-Decrypt-Password when metadata confirms the file is encrypted
- Re-upload files whose encryption metadata may be corrupt
- Pin matching client/server versions to avoid encryption format drift
- Monitor storage backend integrity for truncated blobs
When it happens
Trigger: GET (or HEAD) request for a stored file where X-Decrypt-Password is set but the decryption reader cannot be attached — typically because the stored blob is not encrypted, the key/nonce metadata is missing or corrupt, or the crypto reader construction fails.
Common situations: Client sends a decrypt password to a file uploaded without encryption; storage backend data corrupted or truncated so metadata is invalid; a client automating downloads passes the header unconditionally; mismatched server version after an encryption format change.
Related errors
- gopenpgp: wrong password in symmetric decryption
- Could not delete file.
- Could not retrieve file.
- Internal server error.
- err.Error()
AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05).
Data as JSON: /api/errors/0422c6e3fcd943b5.
Report an issue: GitHub.