Blog

How to fix Google Drive API 404 "File not found" when the file exists

Troubleshoot Google Drive API 404 notFound errors for files that exist. Learn how to identify common causes and fix them.

Shamal Jayawardhana
Shamal Jayawardhana
Dev Relations
API Integrations
Oct 26, 2026
Copy URL

Google Drive API sometimes returns a 404 notFound error for existing files. However, users can open them directly from Google Drive. That means those files are not missing. Google can return a 404 when the API request can’t access the file.

The problem might be related to the Google account behind the access token, the OAuth scopes granted to your app, or whether the user has authorized your app to access that specific file under the drive.file scope.

For example, in customer-facing integrations such as document ingestion, RAG, and AI agents, a user might select a folder in Google Picker. However, the app still gets a 404 when it tries to read files inside it. Selecting a folder doesn’t automatically give the app access to every file it contains.

In this article, we’ll look at the common causes of Google Drive API 404 errors, how to identify them and fix them in your integration.

postman get request 404 response redacted

How to identify the Google Drive 404 error

When a files.get request fails because the file can’t be found or accessed, Google may return a response like this:

{
    "error": {
        "code": 404,
        "message": "File not found: 1lNvi....r5M0.",
        "errors": [
            {
                "message": "File not found: 1lNvi....r5M0.",
                "domain": "global",
                "reason": "notFound",
                "location": "fileId",
                "locationType": "parameter"
            }
        ]
    }
}

According to Google’s Drive error reference, notFound can mean either the file doesn’t exist or the authenticated user doesn’t have read access to it. The response doesn’t tell you which.

Start by requesting the file’s metadata using the same access token that produced the error:

curl -i \
  "https://www.googleapis.com/drive/v3/files/FILE_ID?fields=id,name,mimeType,trashed,driveId,shortcutDetails&supportsAllDrives=true" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Replace FILE_ID with the actual file ID and ACCESS_TOKEN with the OAuth access token used by your integration.

The request includes supportsAllDrives=true to support files in Shared Drives. If your original request failed without this parameter but succeeds after adding it, check whether the file belongs to a Shared Drive. We’ll cover this in cause 6 below.

We’ll use this metadata request throughout the troubleshooting steps to identify what’s preventing access.

Why Drive returns 404 for an existing file

To read a file through the Google Drive API, the following conditions must be met:

CheckQuestionWho controls it
FileIs the ID correct, and does the file still exist?Your code
IdentityWhich Google account (or service account) owns the token?Your auth flow
User accessCan that account read the file in Drive?The file owner or Drive admin
App accessDo the granted scopes cover this file? Under drive.file, did the user authorize this file for your app?Your OAuth and Picker setup
RequestDoes the request carry the parameters this file needs (supportsAllDrives, resource key)?Your code

The difference between user access and app access causes most of the confusion. The user’s Drive permissions are the ceiling. Your scopes decide how much of that ceiling your app gets. With drive.file, your app sees only files the user created with your app, opened with your app, or shared with your app through Google Picker (Google’s scope reference). Everything else in the user’s Drive returns 404 to your app, even though the user can open it.

Because Drive uses 404 for both cases, a caller without read access can’t tell whether the file exists. Treat a Drive 404 as “this token can’t see this file” until you have confirmed the file was deleted.

drive file access authorization diagram

How the drive.file scope limits an app’s access to files the user can access in Google Drive.

Google Drive errors that look similar but are not 404

StatusreasonWhat it meansFirst check
401authErrorExpired or invalid access tokenRefresh the token. If refresh fails, see Google OAuth invalid_grant.
403insufficientPermissionsThe token has no scope that allows this methodGranted scopes (cause 4)
403appNotAuthorizedToFileYour app is not on the file's ACLSame fix as cause 5
403insufficientFilePermissionsThe user can read the file but not write itRequest edit access
403teamDriveMembershipRequiredThe user is not a member of the shared driveAsk the shared drive manager
404notFoundNo read access, or the file does not existThis article

Root causes for Google Drive notFound errors and their fixes

The causes are listed in the order you should check them. I started with the simplest checks, then moved on to OAuth scopes and Picker configuration. Check causes 1–3 before changing OAuth scopes or asking the user to share the file again.

1. The file ID is incorrect, the file was deleted, or a shortcut’s target is unavailable

Why it happens: IDs often come from parsed URLs, old database rows, or Picker callbacks. A permanently deleted file returns 404 for everyone. A Drive shortcut has its own ID, separate from the file it points to. Requesting the shortcut’s metadata can succeed even when its target was deleted or the user can no longer access the target. A shortcut ID alone does not cause a 404.

How to confirm:

  • Take the ID from the /d/FILE_ID/ segment of the file URL, without query parameters like resourcekey.
  • Ask the user to open https://drive.google.com/file/d/FILE_ID/view while signed in to the Google account your app uses.
  • A trashed file still resolves, with "trashed": true. But, you can’t resolve a permanently deleted file with this.
  • If mimeType is application/vnd.google-apps.shortcut, read shortcutDetails.targetId and make a separate files.get request for that ID using the same token. Access to the shortcut does not guarantee access to its target.

How to fix: Correct the file ID and handle "trashed": true in syncs. For shortcuts, resolve the target ID before fetching the target’s content. If the target is inaccessible, have the owner restore access or ask the user to select another file. Recheck the ID and access before retrying a 404 on a file that worked before.

Expected result: A request for an existing file or shortcut target that the app can access returns 200 with its metadata.

2. The token belongs to a different Google account

Why it happens: Many users have a personal Gmail account and a Workspace account in the same browser. They consent with one and look at the file with the other. In multi-tenant products, the backend can also pick the wrong stored connection for a customer.

How to confirm: Use about.get to check which Google account is associated with the access token. This method supports all Google Drive scopes, including drive.file:

curl -s "https://www.googleapis.com/drive/v3/about?fields=user(emailAddress,displayName)" \
  -H "Authorization: Bearer ACCESS_TOKEN"
{
  "user": {
    "displayName": "Jane Doe",
    "emailAddress": "jane@customer.com"
  }
}

Compare emailAddress with the account that can open the file.

Service accounts: A service account is a separate Google identity with its own Drive. It sees only files shared with its ...iam.gserviceaccount.com address. With domain-wide delegation, the token acts as the user set in the subject claim. A missing or wrong subject means you are calling Drive as the wrong identity.

How to fix: Reconnect with the correct account. Adding prompt=select_account to the Google authorization URL forces the account chooser. For service accounts, share the file or folder with the service account email, or impersonate the right user.

Expected result: The about.get request returns the correct Google account email, and the original files.get request succeeds with 200 OK.

3. The user no longer has read access

Why it happens: This can happen when the user-level permissions change. The user may lose access to a file when the owner stops sharing it, the user leaves a group that has access, or a shared drive manager removes their permissions. Your app cannot access files that the authenticated user no longer has permission to read.

How to confirm: The user cannot open the file in the Drive UI either. Shared drive membership problems on other methods may surface as 403 teamDriveMembershipRequired.

How to fix: The owner or the shared drive manager has to restore access. Scope change doesn’t fix this. Surface a message like “You no longer have access to this file in Google Drive” instead of a generic sync failure.

Expected result: Once access is restored, files.get returns 200.

4. The user granted fewer scopes than you requested

Why it happens: The scopes configured in Google Cloud, requested during OAuth, and the scopes the user actually grants don’t always match.

Since January 7, 2026, Google has supported granular OAuth consent for web apps. When your app requests multiple scopes, users can choose which permissions to grant. Your app may still receive a valid access token, even if the user hasn’t granted all the requested scopes.

How to confirm: Check what the token carries with the tokeninfo endpoint:

curl -s "https://oauth2.googleapis.com/tokeninfo?access_token=ACCESS_TOKEN"
{
  "aud": "123456789012-abc123.apps.googleusercontent.com",
  "scope": "https://www.googleapis.com/auth/drive.file openid",
  "expires_in": "3412",
  "access_type": "offline"
}

The scope field is the source of truth. Google’s token response includes the same field at authorization time.

A token with no Drive scope usually fails with 403 insufficientPermissions. A token with a narrower Drive scope than you expected (drive.file instead of drive.readonly) returns 404 for every file outside that scope.

How to fix: Check granted scopes after every authorization. If a required scope is missing, explain why the feature needs it and ask the user to authorize again with include_granted_scopes=true.

If your integration runs on Nango, use a reconnect session to let the user authorize again while preserving the connection’s existing data and configuration.

Expected result: The Google API should return a tokeninfo response that lists the scope your request needs.

5. The file wasn’t authorized for your app under drive.file

If your app uses Google Picker, this is the cause to check most carefully. It has three variants.

Why it happens: drive.file access is per user, per file, and per Google Cloud project. A file becomes visible to your app only when the user creates it with your app, opens it with your app from Drive, or selects it in Google Picker configured for your project. The user being able to open the file is not enough.

Variant A: the user selected the parent folder. Picker lets users select folders with DocsView.setSelectFolderEnabled(true). Under drive.file, that authorizes the folder, not the files inside it. Developers report that after selecting a folder, 'FOLDER_ID' in parents returns an empty list and files.get on a child returns 404 (Stack Overflow, July 2025). Note the two symptoms: listing succeeds with zero results, while fetching a child by ID fails.

In our test, Account B owned a Google Drive folder containing a test document. After selecting only the parent folder through Google Picker, a files.get request for the child document returned 404 notFound.

google drive picker folder 404

The Google Drive API returns 404 notFound before the individual file is authorized for the app.

We then selected the individual document through Picker and repeated the same request. This time, Google returned 200 OK with the file’s ID, name, and MIME type.

google drive picker file 200

The same files.get request returns 200 OK after the user selects the file through Google Picker.

This confirms that selecting a parent folder does not automatically authorize the app to access every file inside it under the drive.file scope.

Variant B: Picker is tied to a different Cloud project than your backend token. Google’s Picker guide uses PickerBuilder.setAppId with the Cloud project number “to allow the app to access the user’s files.” If setAppId is missing, holds the project ID string instead of the numeric project number, or points to a different project than your backend’s OAuth client, the backend token can’t see the selected file. Developers report this failing for only some files or accounts, and working in testing but failing in production (Stack Overflow).

To check, compare the setAppId value with the project that owns the client ID in tokeninfo’s aud field. Google OAuth client IDs start with the project number (123456789012-...apps.googleusercontent.com).

Variant C: the file was added after the user’s last selection. New files in a selected folder, or files shared with the user later, are not authorized until the user selects them.

How to fix: Configure Picker to select files, not folders, and tie it to the right project:

// Users can browse into folders, but can only select files.
const myDriveView = new google.picker.DocsView(google.picker.ViewId.DOCS)
  .setLabel('My Drive')
  .setIncludeFolders(true)
  .setSelectFolderEnabled(false)
  .setEnableDrives(false);

// A separate view shows shared drives and their files.
const sharedDrivesView = new google.picker.DocsView(google.picker.ViewId.DOCS)
  .setLabel('Shared drives')
  .setIncludeFolders(true)
  .setSelectFolderEnabled(false)
  .setEnableDrives(true);

const picker = new google.picker.PickerBuilder()
  .addView(myDriveView)
  .addView(sharedDrivesView)
  .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
  .setOAuthToken(accessToken)           // token from the same OAuth client as your backend
  .setAppId('123456789012')             // numeric Cloud project number, not the project ID
  .setDeveloperKey(API_KEY)
  .setCallback(onPicked)
  .build();

picker.setVisible(true);

When the backend hits a 404 for a known file ID, reopen Picker with a dedicated DocsView that uses DocsView.setFileIds to show that file. The user must select the file and click Select to authorize it for the app. setFileIds controls which files appear; it does not preselect them. Do not combine it with setEnableDrives or setParent on the same view, because these settings override one another. Files the user cannot access are excluded from the view.

If your product needs “sync this folder, including files added later”, drive.file cannot do that. See the section on choosing the right fix below.

Nango’s pre-built documents sync accepts selected file IDs in connection metadata. With a scope that permits folder access, it can also sync file metadata recursively from selected folders, including shared drives.

Expected result: After the user selects the individual file in a correctly configured Picker, the same files.get request with the same backend token returns 200.

6. The file is on a shared drive, and the request omits supportsAllDrives

Why it happens: Requests that do not declare shared drive support don’t see shared drive files. Google lists this as the first fix for notFound in its error reference.

How to confirm: The same request succeeds once you add supportsAllDrives=true, and the response includes a driveId.

How to fix: Add supportsAllDrives=true to files.get, files.list, files.create, files.update, files.copy, files.delete, changes.list, and the relevant permissions methods (see the full list).

For files.list and changes.list, also set includeItemsFromAllDrives=true. Otherwise, shared drive items may be excluded from the results.

In Google Picker, add a separate DocsView with setEnableDrives(true) so users can browse shared drives. This setting shows only shared drives in that view; keep the My Drive view separate, as in the example above.

Expected result: The files.get request should return 200 OK, confirming that the file is accessible. The response should also include the driveId field containing the shared drive’s ID, provided you requested that field.

Why it happens: Some files shared with “anyone with the link” or “anyone in the domain” have a resource key. Users who reach the file only through that link and have not viewed it before must send the key. Users with direct access do not need it.

How to confirm: The file URL contains a resourcekey= parameter, and the user’s access comes from link sharing, not from a direct share.

How to fix: Store the key when you first see the file (the resourceKey field on the file resource, or shortcutDetails.targetResourceKey for shortcuts) and send it on every request:

curl -s "https://www.googleapis.com/drive/v3/files/FILE_ID?fields=id,name&supportsAllDrives=true" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "X-Goog-Drive-Resource-Keys: FILE_ID/RESOURCE_KEY"

Expected result: The request should return 200 OK, confirming that your app can now access the file. The response should include the file metadata you requested, such as its ID, name, and MIME type.

Reproducing the folder-versus-file behavior under drive.file

We reproduced the drive.file authorization issue using a test Google account, Google Picker, and Postman.

Here’s the setup we used:

  • Google account: A dedicated test Gmail account (Account B).
  • OAuth client: A web application client in a test Google Cloud project, configured with the https://www.googleapis.com/auth/drive.file scope.
  • Google Picker: Configured with setAppId using the same Cloud project’s numeric project number.
  • Test data: A folder named CON-322 Picker Test, containing a Google Docs document named Drive API Child File Test.

We used Postman to send a files.get request for the same document before and after selecting it individually through Google Picker.

#ScenarioRequestObserved result
1Before selecting the individual filefiles.get for Drive API Child File Test404 Not Found, with reason notFound
2After selecting the individual file in Pickerfiles.get for the same document200 OK, returning the file's ID, name, and MIME type

Before selecting the file

The document existed in Google Drive, and the test account could open it. However, our initial files.get request returned 404 Not Found because the app had not yet been granted access to that specific file.

google drive picker folder 404

The Google Drive API returned 404 notFound before the individual file was selected through Google Picker.

After selecting the file

We then selected Drive API Child File Test through Google Picker and repeated the request using the same file ID.

This time, the API returned 200 OK with the document’s metadata.

google drive picker file 200

The same files.get request succeeded after selecting the file through Google Picker.

The results show that having access to a file in Google Drive doesn’t automatically give an app access under drive.file. The app must also be authorized to access that specific file.

Selecting the individual file through Google Picker resolved the error in our test.

Choosing the right fix

Start with the least privileged option that solves the problem. Broader scopes are a last resort.

  1. Fix the request or identity: Fix wrong ID, wrong account, missing supportsAllDrives, missing resource key, or a Picker setAppId mismatch. You don’t need to change the scope or create new verification at first.
  2. Have the user select individual files with Picker (drive.file): drive.file is non-sensitive and it needs only basic OAuth app verification. The tradeoff is that users must select each file, including files added later.
  3. Let your app create the files: drive.file covers files your app creates. If your product owns the folder structure (exports, generated reports), create the files through the API and they stay visible to your app.
  4. Request a broader read scope: drive.readonly (and drive.metadata.readonly) are restricted scopes. Google only allows them for specific app types (backup and sync, productivity and education, reporting and security). Apps that store or transmit restricted-scope data on servers also need a CASA security assessment and need to renew the assessment every 12 months. With preparation, Nango customers typically complete verification plus CASA in 5 to 20 days. Choose this only if your product needs folder-level or whole-Drive access, such as syncing a folder for RAG.

If you use your own Google OAuth app, plan the review time before you switch. While a Google OAuth app is in testing, it is capped at 100 users and its refresh tokens expire after 7 days.

Nango also offers a managed Google Drive OAuth app that has completed Google verification and the CASA security assessment and is available for development and production. Use its supported scopes, or bring your own OAuth app for custom scopes and your product’s branding on the consent screen.

Quick reference for Google Drive 404

SymptomLikely causeHow to checkFix
404 for everyone, ID came from an old recordDeleted or wrong IDOpen drive.google.com/file/d/FILE_ID/viewRecheck the ID, handle deletes
Shortcut metadata loads, but fetching its target returns 404Target deleted or inaccessible to the appRequest shortcutDetails.targetId with the same tokenRestore target access or select another file
User sees the file, app does not, only some usersWrong Google accountabout.get user.emailAddressReconnect with the right account
User cannot open the file eitherSharing revokedDrive UIOwner restores access
404 on many files, scope looks right in configNarrower scope grantedtokeninfo scopeReauthorize with the needed scope
Folder picked, children 404, listing emptydrive.file folder selectionPicker configSelect files, not folders
Picked file 404 in backendsetAppId missing or wrong projectCompare project number with tokeninfo audSet the numeric project number
Works after adding supportsAllDrives=trueShared drive fileResponse has driveIdSet it on every request
URL has resourcekey=Link-shared fileCheck the file URLSend X-Goog-Drive-Resource-Keys

Debugging Google Drive 404s through Nango

Nango connects AI agents and SaaS products to 1,000+ APIs. It ships 10,000+ pre-built tools and covers auth, tool calls, triggers and syncs. For Google Drive, it ships 30 pre-built actions and 4 syncs you can customize, covering file operations, document metadata, folders, permissions, and shared drives.

If your Google Drive integration runs on Nango, the same diagnostics work through the Nango proxy. The proxy injects the connection’s access token, refreshes it when needed, and passes Google’s status and error body back to you.

The baseline files.get request:

curl -i \
  "https://api.nango.dev/proxy/drive/v3/files/FILE_ID?fields=id,name,mimeType,trashed,driveId,shortcutDetails&supportsAllDrives=true" \
  -H "Authorization: Bearer NANGO_API_KEY" \
  -H "Provider-Config-Key: google-drive" \
  -H "Connection-Id: CONNECTION_ID" \
  -H "Base-Url-Override: https://www.googleapis.com"

Or with the Node SDK:

import { Nango } from '@nangohq/node';

const nango = new Nango({ apiKey: process.env.NANGO_API_KEY! });

const res = await nango.get({
  endpoint: `/drive/v3/files/${fileId}`,
  params: { fields: 'id,name,mimeType,trashed,driveId', supportsAllDrives: 'true' },
  providerConfigKey: 'google-drive',
  connectionId
});

We tested a files.get request through Nango’s API proxy using a Google Drive connection configured with the drive.file scope. When we requested a file the app couldn’t access, Google returned 404 Not Found with the reason notFound.

nango google drive proxy 404 error

Google Drive returning 404 notFound through Nango’s API proxy.

To troubleshoot a Google Drive 404 error through Nango, check the following details for the affected connection:

  • Connection: find the failing call in the Logs view to confirm which connectionId it used and what Google returned.
nango google drive proxy success failure logs

Nango Logs showing successful and failed Google Drive API proxy requests for the same connection.

  • Google account: call /drive/v3/about?fields=user through the proxy with the same connection, or run the pre-built get-about action.
  • Configured scopes: check the scopes on the Google Drive integration in the Nango dashboard. These are what Nango requests during authorization.
  • Granted scopes: Fetch the connection using Nango’s GET /connections/{connectionId} endpoint and inspect the OAuth credential metadata. In our test, credentials.raw.scope contained https://www.googleapis.com/auth/drive.file, matching the scope configured for the Google Drive connection.
nango google drive granted oauth scope

Nango’s Get Connection API response showing the drive.file scope in credentials.raw.scope.

The scope field was present in our test, but its availability may vary depending on the provider’s OAuth response. If it’s missing, you can check the active access token’s scopes using Google’s token inspection endpoint. Recheck the granted scopes after reconnecting an account, since the user may authorize different permissions.

Nango manages the connection and its credentials. It does not change Google’s sharing permissions or drive.file per-file authorization: a file the user has not authorized for your project returns the same 404 through Nango as it does directly. Your frontend still runs Google Picker with the Cloud project number associated with the connection’s OAuth app and a token from the connection.

The Nango sample app shows the full flow: connecting Google Drive, selecting files with Google Picker, syncing document metadata, and downloading file contents. To keep a RAG index current, you can also route Drive change notifications through Nango and trigger a sync for the affected connection.

Ready to get started?

Ship the integrations your customers need — with 1,000+ APIs and infrastructure built for scale.