# Chart.js Chart Not Showing — Every Cause, Matched to the Console Error

Canonical: https://commareports.com/fix/chartjs-chart-not-showing
Published: 2026-10-10

> A blank canvas where the Chart.js chart should be. Match the console message — can't acquire context, Chart is not defined, not a registered controller, canvas already in use — to its fix, plus the silent cases: zero-height containers, v2 options in v4, and blank PDFs.

# The Chart.js chart isn't showing

The page loads. There's a gap — or nothing at all — where the chart should
be. Chart.js almost never fails loudly on the page itself, but it nearly
always says something in the console. Open DevTools (F12 → Console) and
match the message.

## Match the console message

| Console says                                                        | Cause                                          |
| ------------------------------------------------------------------- | ---------------------------------------------- |
| `Failed to create chart: can't acquire context from the given item` | The canvas wasn't found when the script ran    |
| `Uncaught ReferenceError: Chart is not defined`                     | The library never loaded                       |
| `"bar" is not a registered controller.`                             | Chart.js 3+ imported without registering types |
| `Canvas is already in use. Chart with ID '0' must be destroyed…`    | A second chart on the same canvas              |
| Nothing, chart area is empty or flat                                | Zero-size container, or v2 options in v3/v4    |
| `Access to fetch at 'file:///…' … has been blocked by CORS policy`  | Data loaded with `fetch()` from a local file   |

### "Can't acquire context from the given item"

`new Chart(el, config)` got `null`. The script ran before the browser
parsed the `<canvas>`, or the id doesn't match.

```html
<canvas id="sales"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<script>
  // After the canvas, so getElementById finds it.
  new Chart(document.getElementById("sales"), { type: "bar", data: { … } });
</script>
```

If the script has to live in `<head>`, give it `defer` or wrap the code in
`document.addEventListener("DOMContentLoaded", …)`.

### "Chart is not defined"

The global `Chart` only exists once the library's `<script>` has run.
Check, in order:

1. **The tag is above your code.** Scripts run top to bottom.
2. **The request succeeded.** The Network tab shows a failed or blocked
   request for `chart.umd.js` or `chart.min.js` when you're offline, behind a
   proxy that blocks the CDN, or inside a viewer whose Content-Security-Policy
   refuses it — [CSP versus mixed content](/fix/mixed-content-blocked-html-report).
3. **A local copy travelled with the page.** `<script src="chart.min.js">`
   works on your machine and 404s once only the `.html` file is sent — the
   same trap as [a report that lost its CSS](/html-report-broken-css).

### "is not a registered controller"

Chart.js 3 made the npm package tree-shakeable. With a bundler,
`import { Chart } from "chart.js"` registers no chart types, scales or
elements.

```js
import Chart from "chart.js/auto"; // everything registered
```

Or register exactly what you use: `Chart.register(BarController,
BarElement, CategoryScale, LinearScale, Tooltip, Legend)`. A missing scale
produces the sibling error, `"category" is not a registered scale`.

### "Canvas is already in use"

You built a new chart on a canvas that still holds the old one — usually
in a function that re-runs when a filter changes. Keep the instance:

```js
let chart;
function render(data) {
  if (chart) chart.destroy();
  chart = new Chart(canvas, { type: "line", data });
}
```

Updating in place (`chart.data = data; chart.update();`) is cheaper and
keeps the animation smooth.

## The silent failures

**The chart has no height.** Responsive charts size from their parent.
`maintainAspectRatio: false` tells the canvas to take the parent's
height — and a `div` with no explicit height has none. Give the wrapper a
real size and keep it for the chart alone:

```html
<div style="position: relative; height: 320px">
  <canvas id="sales"></canvas>
</div>
```

**It was created while hidden.** A chart built inside a `display: none`
tab, accordion or modal measures 0×0. Create it when the panel opens, or
call `chart.resize()` then.

**Options from a Chart.js 2 tutorial.** `scales: { yAxes: [{ … }] }` and
`ticks: { beginAtZero: true }` under `yAxes` are v2 syntax; v3 and v4
expect `scales: { y: { beginAtZero: true } }` and ignore the old shape
without an error. A CDN URL without a version — `npm/chart.js` — serves
the latest major, so a page that worked for years can change underneath
you. Pin it: `npm/chart.js@4`.

**Blank in the PDF or screenshot.** The capture fired mid-animation. Set
`animation: false` for anything printed, screenshotted or rendered
headless — see [HTML to PDF](/tools/html-to-pdf) and
[HTML to image](/tools/html-to-image).

**Data from a local JSON file.** `fetch("data.json")` from a page opened
as `file://` is blocked — [CORS error from origin 'null'](/fix/cors-error-file-origin-null).
Inline the data in the page instead.

## Or skip the script entirely

If the chart only has to be _read_ — in a report, a pull request, an
email — it doesn't need a runtime library. Paste the numbers into
[CSV to chart](/tools/csv-to-chart), or paste your Chart.js `{ labels,
datasets }` object straight into [JSON to chart](/tools/json-to-chart),
and get a static SVG bar, line or pie chart with no script, no CDN and
nothing to fail to load.

## Sharing a chart that works

When the Chart.js page is right, send a link, not the file. Published to
Comma, scripts run in a sandboxed iframe (`allow-scripts`, no
`allow-same-origin`), so tooltips, legend toggles and animations work, and
the common CDNs load inside the frame. Reviewers select the number next to
the chart and comment on it in place instead of screenshotting it into
chat. One caveat: a published report can't `fetch()` sibling files, so
inline the data before you publish.

**[Publish a chart report →](https://commareports.com/)**

### Related

- [Plotly chart missing from the exported HTML](/fix/plotly-chart-not-showing-in-html)
- [CORS error from origin 'null'](/fix/cors-error-file-origin-null)
- [Interactive HTML reports](/interactive-html-reports)
- [CSV to chart](/tools/csv-to-chart)
- [JSON to chart](/tools/json-to-chart)
