firebase / firebase/firebase-tools

bug(deploy-functions): Functions that failed healthcheck during initial deployment will have missing invocation permissions

Open
#8,984 4 comments 1 reaction 1 assignee Assigned to @cabljac View on GitHub
api: functions reproducible triaged type: bug
Dominant language
TypeScript
Stars
4.5k
Forks
1.3k
Avg merge
1d 12h
Merged PRs (30d)
84

Description

### [REQUIRED] Environment info

**firebase-tools:** 14.11.1

**Platform:** Debian

**Node:** 22

### [REQUIRED] Test case

File: **functions/src/feature.local/somethingModule.ts**
```typescript
export const value = "some value";
```

File: **functions/src/index.ts**
```typescript
import { onRequest } from "firebase-functions/https";

// The module that would not be included in the Cloud Run container.
import { value } from "./feature.local/somethingModule";

export const helloFailingInitialDeploy = onRequest((request, response) => {
response.send(`Hello from Firebase! The value is: ${value}`);
});
```

### [REQUIRED] Steps to reproduce

#### Initialize a new codebase

Run firebase init in an empty dir. Select "functions" from the options to create a boilerplate Node.js project.

#### Implement a function with a bug

Make sure a function with the same name does not already exist in the Firebase console.

We can use the sample code above from the previous section. Which would work locally, but the upload would skip the `feature.local/` dir (per the `*.local` item in the ignore-list in `firebase.json`).

#### Try deploying the buggy function

```shell
firebase deploy --only functions
```

**Ensure that the function fails the initial health check and causes the deployment failure.**

Output tail:
```
Error: There was an error deploying functions
```

full output

```
> deploy
> firebase deploy --only functions:codebase0

=== Deploying to REDACTED...

i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run build

> build
> tsc

✔ functions: Finished running predeploy script.
i functions: preparing codebase codebase0 for deployment
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
i functions: Loading and analyzing source code for codebase codebase0 to determine what to deploy
Serving at port 8281

i extensions: ensuring required API firebaseextensions.googleapis.com is enabled...
i functions: preparing codebase0 directory for uploading...
i functions: packaged REDACTED (3.78 KB) for uploading
i functions: ensuring required API run.googleapis.com is enabled...
i functions: ensuring required API eventarc.googleapis.com is enabled...
i functions: ensuring required API pubsub.googleapis.com is enabled...
i functions: ensuring required API storage.googleapis.com is enabled...
i functions: generating the service identity for pubsub.googleapis.com...
i functions: generating the service identity for eventarc.googleapis.com...
✔ functions: codebase0 folder uploaded successfully
i functions: creating Node.js 22 (2nd Gen) function codebase0:helloFailingInitialDeploy(us-central1)...
Could not create or update Cloud Run service hellofailinginitialdeploy, Container Healthcheck failed. Revision 'hellofailinginitialdeploy-00001-won' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout. This can happen when the container port is misconfigured or if the timeout is too short. The health check timeout can be extended. Logs for this revision might contain more information.

Logs URL: REDACTED
For more troubleshooting guidance, see https://cloud.google.com/run/docs/troubleshooting#container-failed-to-start

Functions deploy had errors with the following functions:
codebase0:helloFailingInitialDeploy(us-central1)

Error: There was an error deploying functions
```

#### Fix the bug and deploy again

Fix `functions/src/index.ts`:
```diff
- import { value } from "./something.local/somethingModule";
+ const value = "some value";
```

Deploy:
```shell
firebase deploy --only functions
```

This time, the deployment should "succeed." Output tail:
```
✔ Deploy complete!
```

Full shell output

```
> deploy
> firebase deploy --only functions:codebase0

=== Deploying to REDACTED...

i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run build

> build
> tsc

✔ functions: Finished running predeploy script.
i functions: preparing codebase codebase0 for deployment
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
i artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
i functions: Loading and analyzing source code for codebase codebase0 to determine what to deploy
Serving at port 8341

i extensions: ensuring required API firebaseextensions.googleapis.com is enabled...
i functions: preparing codebase0 directory for uploading...
i functions: packaged REDACTED (3.77 KB) for uploading
i functions: ensuring required API run.googleapis.com is enabled...
i functions: ensuring required API eventarc.googleapis.com is enabled...
i functions: ensuring required API pubsub.googleapis.com is enabled...
i functions: ensuring required API storage.googleapis.com is enabled...
i functions: generating the service identity for pubsub.googleapis.com...
i functions: generating the service identity for eventarc.googleapis.com...
✔ functions: codebase0 folder uploaded successfully
i functions: updating Node.js 22 (2nd Gen) function codebase0:helloFailingInitialDeploy(us-central1)...
✔ functions[codebase0:helloFailingInitialDeploy(us-central1)] Successful update operation.
Function URL (codebase0:helloFailingInitialDeploy(us-central1)): REDACTED

✔ Deploy complete!

Project Console: REDACTED
```

**However, the permission to invoke the function would not be applied.**

#### Send the request to the function endpoint

### [REQUIRED] Expected behavior

The function invocation permissions must allow public access after a successful deployment.

E.g. the Cloud Run console must show "Public access" in the "Authentication" row.
Image

and invoking the function should return "200 OK":
Image

### [REQUIRED] Actual behavior

Even after successful consequent deployments, the Cloud Run console shows that invocations of the functions "Require authentication":
Image

In a web browser, navigating to the function endpoint returns a "403 Forbidden" error:
Image

#### Additional info

When looking at the outputs and project console on Google Cloud, I noticed that during the secondary deployment (which, according to `firebase-tools`, "succeeds"), the output does not say "creating Node.js 22 (2nd Gen) function ..." Instead, it prints "updating Node.js 22 (2nd Gen) function ..."

From this, it appears that setting IAM policies is skipped on "updates," even when the initial deployment bailed out before setting them (so, the policies end up never getting applied). I have not tried it yet, but this could mean that if the initial deployment of a function in a different region fails, the same bug may occur.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.