Back to Support
Troubleshooting

403 Forbidden on Transcode

Common causes of 403 Forbidden errors and how to fix bucket permissions

403 Forbidden on Transcode


If you're getting a 403 Forbidden error when creating a transcode job, it's usually a permissions issue with your storage bucket.


Common Cause: Incorrect Bucket URL


The most common mistake is using a placeholder or example bucket name from the documentation:


❌ Common Mistakes


{
  "inputs": [
    { "url": "gs://your-bucket/video.mp4" }  // ❌ Literal "your-bucket"
  ]
}

{
  "inputs": [
    { "url": "gs://example-bucket/video.mp4" }  // ❌ Example bucket
  ]
}

{
  "inputs": [
    { "url": "gs://my-bucket/video.mp4" }  // ❌ Doesn't exist
  ]
}

✅ Correct Format


Use the actual bucket name from your presigned upload URL:


{
  "inputs": [
    { "url": "gs://ffmpeg-micro-uploads-prod/1234567890-video.mp4" }
  ]
}

How to Get the Correct Bucket URL


Option 1: Use the Presigned Upload Flow


When you upload via the presigned URL flow, save the full GCS URL:


// 1. Get presigned URL
const { uploadUrl, filename } = await fetch('/v1/upload/presigned-url', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    filename: 'video.mp4',
    contentType: 'video/mp4',
    fileSize: 12345678
  })
}).then(r => r.json())

// 2. Upload file
await fetch(uploadUrl, {
  method: 'PUT',
  body: file
})

// 3. Construct GCS URL for transcode
const gcsUrl = `gs://ffmpeg-micro-uploads-prod/${filename}`

// 4. Create transcode job
await fetch('/v1/transcodes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    inputs: [{ url: gcsUrl }],  // ✅ Correct!
    outputFormat: 'mp4',
    preset: { quality: 'medium' }
  })
})

Other 403 Causes


1. Quota Exceeded


Your account may have hit its monthly quota limit. Check your usage at /dashboard/usage.


Solution: Upgrade your plan or wait until the next billing cycle.


2. API Key Revoked


If you've deleted or regenerated your API key, the old key will return 403.


Solution: Get your current API key from /dashboard/api-keys.


3. Account Suspended


In rare cases, accounts may be suspended for violations of the terms of service.


Solution: Contact support at javid@ffmpeg-micro.com.


Quick Debugging Steps


  • Check the bucket URL: Is it gs://ffmpeg-micro-uploads-prod/... or gs://your-bucket/...?
  • Verify the file exists: Did the upload complete successfully?
  • Check your quota: Visit /dashboard/usage
  • Test your API key: Try the health check endpoint

  • Example: Complete Upload & Transcode Flow


    # 1. Get presigned upload URL
    UPLOAD_RESPONSE=$(curl -X POST "https://api.ffmpeg-micro.com/v1/upload/presigned-url" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "filename": "video.mp4",
        "contentType": "video/mp4",
        "fileSize": 12345678
      }')
    
    UPLOAD_URL=$(echo $UPLOAD_RESPONSE | jq -r '.result.uploadUrl')
    FILENAME=$(echo $UPLOAD_RESPONSE | jq -r '.result.filename')
    
    # 2. Upload file
    curl -X PUT "$UPLOAD_URL" \
      -H "Content-Type: video/mp4" \
      --data-binary @video.mp4
    
    # 3. Confirm upload
    curl -X POST "https://api.ffmpeg-micro.com/v1/upload/confirm" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{
        \"filename\": \"$FILENAME\",
        \"fileSize\": 12345678
      }"
    
    # 4. Create transcode with correct GCS URL
    curl -X POST "https://api.ffmpeg-micro.com/v1/transcodes" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{
        \"inputs\": [{
          \"url\": \"gs://ffmpeg-micro-uploads-prod/$FILENAME\"
        }],
        \"outputFormat\": \"mp4\",
        \"preset\": {
          \"quality\": \"medium\"
        }
      }"
    

    Still Getting 403?


    Contact support at javid@ffmpeg-micro.com with:

  • The exact error message
  • The bucket URL you're using
  • The job ID (if available)
  • Your API key (first 8 characters only)