# FAQ and troubleshooting Common questions and the quick fixes. If something here doesn't cover your case, the relevant reference page usually does. ## Setup and keys **"Error: No API key set."** zfin needs at least `TIINGO_API_KEY` to fetch price history. Set it in your environment or `.env`. See [Getting started](../getting-started.md) and [environment variables](../reference/config/environment.md#api-keys). **Total-return columns are blank or match price-only.** Total return needs dividend data from Polygon -- set `POLYGON_API_KEY`. Without it you get price-only returns. See [Returns and performance](returns-and-performance.md#price-only-vs-total-return). **ETF profiles or `enrich` don't work.** SEC EDGAR requires a contact email. Set `ZFIN_USER_EMAIL` to your address (it's not a key). See [`zfin enrich`](../reference/cli/enrich.md). ## Missing or odd data **A holding shows up as "Unclassified."** It has no [`metadata.srf`](../reference/config/metadata-srf.md) entry, or the entry's `symbol::` doesn't match the lot's `symbol::`/`ticker::`. Add a classification line; see [Classify your holdings](../guides/classify-holdings.md). **An account shows as "Unknown" in the tax-type breakdown.** It's missing from [`accounts.srf`](../reference/config/accounts-srf.md), or the `account::` name doesn't match the lot's `account::` exactly (names must match character-for-character). See [Map your accounts](../guides/set-up-accounts.md). **My 401(k) lumps Roth and pre-tax money into one balance, so the tax-type breakdown is wrong.** Declare the split instead of picking a side. Add a percentage carve-out to the account and `tax_type` keeps the remainder: ```srf account::Sample 401k,tax_type::traditional,tax_mix_roth:num:22.4,tax_mix_date::2026-08-01 ``` The account then contributes to both the Traditional and Roth rows, weighted by value. Don't split the account in two in `portfolio.srf` to work around this -- two accounts can't share one `account_number` (breaking audit reconciliation), you'd be hand-splitting every lot into fractional shares on each contribution, and it permanently forks the account's snapshot history. See [Mixed tax treatment](../reference/config/accounts-srf.md#mixed-tax-treatment). **A stock or ETF shows "no earnings data."** ETFs, mutual funds, CUSIPs, and some dual-class shares (e.g. BRK.B) return no earnings on FMP's free tier. This is an expected limitation, not a bug. See [Why multiple data providers](data-providers.md). **A mutual fund price looks like yesterday's.** Mutual-fund NAVs publish after market close (after midnight ET for some funds), so intraday you'll see the prior NAV until the new one posts. **`quote` says the symbol is unavailable, but `perf` works.** You're probably in offline mode (`--refresh-data=never`). Quotes are never cached, so offline there's nothing to serve; candle-based commands still work from cache. See [Caching and data freshness](caching.md#quotes-are-never-cached). **A row is shown in warning (yellow) color.** That's a manual-priced lot -- its price came from the lot's `price::` field, not a live feed, so it may be stale. Update `price::` / `price_date::`, or run [`zfin audit`](../reference/cli/audit.md) to find stale ones. ## Behavior **A run printed "(using cached data)."** zfin served fresh-enough cached data instead of hitting the network -- normal and fast. Force a refetch with `--refresh-data=force`. See [Offline use and refreshing data](../guides/offline-and-refresh.md). **A refresh seems slow / pauses.** The rate limiter is spacing requests to stay under a provider's free-tier limit (e.g. Polygon 5/min). It blocks rather than failing. See [rate limiting](caching.md#rate-limiting). **zfin can't find my portfolio.** It looks in `ZFIN_HOME` if set, otherwise the current directory. Set `ZFIN_HOME` to your data directory, or `cd` into it. `accounts.srf` and `metadata.srf` load from the same directory as the resolved `portfolio.srf`. See [core concepts](concepts.md#zfin_home-where-your-data-lives). **CLI and TUI show different totals.** They shouldn't -- both union-merge every `portfolio*.srf` in `ZFIN_HOME`. If they differ, check whether you passed a narrowing `-p` pattern to one but not the other, or whether one is using a stale cache vs. live prices. **`contributions` reports "No changes detected."** It diffs git revisions of your portfolio. With a clean tree it compares `HEAD~1..HEAD`; if your last commit didn't change holdings, there's nothing to show. Use `--since` to widen the window. See [Track contributions](../guides/track-contributions.md). ## Data hygiene **Lots of "overdue for update" accounts in `audit`.** The default cadence is weekly and nags until satisfied. Set `update_cadence::monthly|quarterly|none` per account in [`accounts.srf`](../reference/config/accounts-srf.md#update_cadence-and-the-audit-nag). **A transfer between my accounts inflated my contributions.** Declare it in [`transaction_log.srf`](../reference/config/transaction-log-srf.md) so it isn't counted as new money. See [Track contributions](../guides/track-contributions.md#dont-double-count-transfers). **`compare` / `contributions` shows a big new lot I never bought, and `audit` flags it under "Large new lots".** Did you rename an account? The account name is zfin's only identifier for an account, and it's part of each lot's identity key -- so renaming one makes every lot in it look like it was closed and re-bought elsewhere. It's cosmetic and happens only for the one review window that straddles the rename commit; nothing is corrupted. See [Renaming an account](../guides/set-up-accounts.md#renaming-an-account) for the full list of consequences, and why account names should be chosen to never change. **I want to see my tax-loss-harvested total, but the account is a synthetic proxy so zfin can't compute it.** Record it by hand with [`harvested` / `harvested_date`](../reference/config/accounts-srf.md#harvested-and-harvested_date) in `accounts.srf`. Don't encode it in the account name -- see the entry above for why. ## See also - [Core concepts](concepts.md) -- the mental model. - [Documentation home](../README.md) -- everything else.