The Empty Secret That Broke Every Azure Function Key Vault Reference

Image of an Azure-style Key vault with one empty glowing slot causing surrounding locks to fail
Generated by ChatGPT

Summary

Azure Function App Key Vault references can fail with the generic OtherReasons status for many reasons: identity, RBAC, networking, platform state, or resolver issues. In this case, the root cause was much simpler and much harder to spot: one or more Key Vault secrets had empty string values created through Bicep.

The Azure Portal would not normally let us create those empty secrets manually, but infrastructure-as-code could. Once the Function App referenced those empty secrets, Key Vault reference resolution failed more broadly than expected, making healthy references look broken too.

The Symptom

The Function App had several application settings using Key Vault reference syntax:

@Microsoft.KeyVault(VaultName=<vault-name>;SecretName=<secret-name>)

Instead of resolving to secret values, the references returned:

status: OtherReasons
details: Reference was not able to be resolved.

The more useful check was the app settings list API. It still returned the literal @Microsoft.KeyVault(...) string, which meant the worker was not receiving the resolved secret value.

At first glance, this looked like a managed identity or platform issue.

The False Trail

We checked the usual suspects.

The Function App identity was attached. The user-assigned managed identity had access to the vault. The Key Vault was reachable. Secret reads were fast and successful. A fresh Function App with the same vault and identity wiring worked.

Because this was on Azure Functions Flex Consumption, the investigation naturally drifted toward Flex-specific behavior. Flex has a different hosting model from classic App Service-backed plans, and some familiar diagnostics paths are not available in the same way. There are also public reports of Flex Consumption managed identity edge cases, including Azure Functions host issue #10904.

That made the theory plausible: maybe the original app had stale platform identity state.

It was plausible, but it was not the root cause. It got to the point where Claude gave up on the troubleshooting

Claude Gives Up

The Actual Root Cause

The issue was empty Key Vault secrets.

Some secrets had been deployed with empty string values through Bicep. The Azure Portal would not let us create the same empty secret values manually, which made this especially non-obvious.

The observed behavior was worse than a single bad setting failing. Once the Function App referenced the empty secrets, Key Vault reference resolution appeared to fail more broadly for the app. Settings that referenced non-empty secrets also failed to resolve.

That cascade is what made the problem look like identity, RBAC, networking, or Function App corruption.

The fix was to remove the application settings that referenced the empty secrets, or replace the empty secret values with non-empty placeholder values. After that, the Key Vault references started resolving again.

Check Empty Secrets First

Before rebuilding the Function App or opening a Microsoft support ticket, check whether any referenced secrets are empty.

This snippet prints only secret names and value lengths. It does not print secret values.

az keyvault secret list \
  --vault-name "<vault-name>" \
  --query "[].name" \
  -o tsv |
while read secret; do
  length=$(az keyvault secret show \
    --vault-name "<vault-name>" \
    --name "$secret" \
    --query "length(value)" \
    -o tsv)

  echo "$secret: length=$length"
done

Any referenced secret with length=0 is suspicious.

If secret names are sensitive in your environment, scope this to the known list of secrets referenced by the Function App instead of listing the whole vault.

A Practical Diagnostic Order

When Key Vault references fail on an Azure Function App, I now check in this order:

  1. Confirm the app setting is still a Key Vault reference.
  2. Check /config/appsettings/list to see whether the worker is getting a real value or the literal reference string.
  3. Confirm the Function App identity has Key Vault Secrets User or equivalent access.
  4. Confirm vault networking is not blocking the app.
  5. Check every referenced secret for empty values.
  6. Only then investigate hosting plan quirks, stale identity state, or platform support.

The fifth step is the one I would now move much earlier. It takes minutes and can save hours.

Why This Is Easy To Miss

The misleading part is that the error message is global and vague.

OtherReasons does not say "one referenced secret is empty." It simply says the reference could not be resolved. If several settings fail at once, the natural assumption is that the common dependency is broken: the identity, the vault, the network path, or the Function App platform.

In our case, the common dependency was the resolver path itself reacting badly to an empty secret value.

This is also a reminder that infrastructure-as-code can create states that the portal UI prevents. That is not always bad, but it means portal validation is not the same thing as platform validation.

Preventing It In Bicep

If your Bicep template creates Key Vault secrets, avoid defaulting secret parameters to empty strings.

Instead of allowing this shape:

@secure()
param apiKey string = ''

Prefer making the value explicit, or conditionally skipping optional secrets until you have a real value.

If a secret is optional, consider not creating the Key Vault secret and not creating the Function App setting that references it. A missing optional setting is usually easier to reason about than a present setting pointing at an empty secret.

Conclusion

This looked like a Flex Consumption managed identity issue. It looked like stale Function App state. It looked like a Key Vault resolver bug.

The actual cause was an empty secret value created through infrastructure-as-code.

If your Azure Function App Key Vault references suddenly all show OtherReasons, do not start by rebuilding the app. Start by checking the referenced secret values. Empty secrets are quick to detect, easy to fix, and capable of causing a much bigger-looking failure than you would expect.

References