# Bad value “” for attribute “src” on element “source”: Must be non-empty.

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-for-attribute-src-on-element-source-must-be-non-empty
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `<source>` element is used inside `<video>`, `<audio>`, and `<picture>` elements to specify one or more media resources for the browser to choose from. Its `src` attribute is defined as a **valid non-empty URL**, meaning it must resolve to an actual file path or web address. An empty string does not satisfy this requirement and violates the HTML specification.

## Why this is a problem

**Standards compliance:** The WHATWG HTML living standard explicitly requires the `src` attribute on `<source>` to be a non-empty, valid URL. An empty value makes the document invalid HTML.

**Unexpected browser behavior:** When a browser encounters an empty `src`, it may attempt to resolve it relative to the current page URL. This can trigger an unnecessary HTTP request back to the current page, resulting in wasted bandwidth, unexpected server load, or confusing errors in your network logs.

**Broken media playback:** An empty `src` means the browser has no media file to load. If the `<source>` element is the only one provided, the media element will fail to play entirely — often without a clear indication to the user of what went wrong.

**Accessibility concerns:** Screen readers and assistive technologies rely on well-formed HTML. Invalid markup can lead to unpredictable behavior or missed content announcements for users who depend on these tools.

## How to fix it

1. **Provide a valid URL** — Set the `src` attribute to the correct path or URL of your media file.
2. **Remove the element** — If the media source is not yet available or is being set dynamically via JavaScript, remove the `<source>` element from the HTML entirely and add it later through script when the URL is known.
3. **Check for template or CMS issues** — This error often appears when a CMS or templating engine outputs a `<source>` tag with an empty variable. Ensure your template conditionally renders the element only when a valid URL exists.

## Examples

### Incorrect: empty `src` on `<source>` in a video

```html
<video controls>
  <source src="" type="video/mp4">
  Your browser does not support the video tag.
</video>
```

### Correct: valid URL in `src`

```html
<video controls>
  <source src="movie.mp4" type="video/mp4">
  Your browser does not support the video tag.
</video>
```

### Incorrect: empty `src` on `<source>` in a picture element

```html
<picture>
  <source src="" type="image/webp">
  <img src="photo.jpg" alt="A sunset over the ocean">
</picture>
```

Note that `<source>` inside `<picture>` uses `srcset`, not `src`. This example is doubly wrong — the attribute is both empty and incorrect. Here is the fix:

### Correct: using `srcset` with a valid URL in a picture element

```html
<picture>
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="A sunset over the ocean">
</picture>
```

### Incorrect: multiple sources with one empty `src`

```html
<audio controls>
  <source src="song.ogg" type="audio/ogg">
  <source src="" type="audio/mpeg">
</audio>
```

### Correct: remove the source if no file is available

```html
<audio controls>
  <source src="song.ogg" type="audio/ogg">
  <source src="song.mp3" type="audio/mpeg">
</audio>
```

### Correct: conditionally add sources with JavaScript

If the URL is determined at runtime, avoid placing an empty `<source>` in your markup. Instead, add it dynamically:

```html
<video id="player" controls>
  Your browser does not support the video tag.
</video>
<script>
  const videoUrl = getVideoUrl(); // your logic here
  if (videoUrl) {
    const source = document.createElement("source");
    source.src = videoUrl;
    source.type = "video/mp4";
    document.getElementById("player").appendChild(source);
  }
</script>
```

This approach keeps your HTML valid at all times and only inserts a `<source>` element when a real URL is available.
