# Bad value “” for attribute “maxlength” on element “textarea”: The empty string is not a valid non-negative integer.

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-for-attribute-maxlength-on-element-textarea-the-empty-string-is-not-a-valid-non-negative-integer
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `maxlength` attribute controls the maximum number of characters a user can type into a `<textarea>`. According to the HTML specification, its value must be a **valid non-negative integer** — that is, a string of one or more ASCII digits like `0`, `100`, or `5000`. An empty string (`""`), whitespace, negative numbers, or non-numeric values are all invalid. When the browser encounters an invalid `maxlength` value, its behavior becomes unpredictable — some browsers may ignore the attribute, while others may silently enforce no limit, leading to inconsistent form behavior across platforms.

This issue frequently arises when a server-side template or JavaScript framework conditionally outputs the `maxlength` attribute but produces an empty value when no limit is configured. For example, a template like `maxlength="{{ maxChars }}"` will render `maxlength=""` if the `maxChars` variable is empty or undefined. The fix is to ensure the attribute is omitted entirely when no value is available, rather than rendering it with an empty string.

Omitting `maxlength` allows unlimited input. Setting it to `0` is technically valid but prevents the user from entering any characters at all, which is rarely useful. Choose a value that makes sense for your use case, such as the corresponding database column's character limit.

## Why this matters

- **Standards compliance:** The HTML specification explicitly requires a valid non-negative integer. An empty string violates this rule and produces a validation error.
- **Consistent behavior:** Browsers handle invalid attribute values differently. A valid value ensures the character limit works reliably across all browsers.
- **Accessibility:** Screen readers and assistive technologies may announce the maximum character limit to users. An empty or invalid value could cause confusing announcements or be silently ignored.
- **Form reliability:** If your application depends on `maxlength` for client-side input restrictions (e.g., to match a database column limit), an invalid value means the constraint isn't enforced, potentially leading to data truncation or server errors.

## How to fix it

1. **Set a specific integer value** if you need a character limit: `maxlength="200"`.
2. **Remove the attribute entirely** if no limit is needed. An absent `maxlength` means unlimited input.
3. **Fix your templates** — if you're using a server-side language or JavaScript framework, conditionally render the attribute so it's omitted when no value is provided rather than output as empty.

## Examples

### ❌ Invalid: empty `maxlength` value

The empty string is not a valid non-negative integer, so this triggers the validation error.

```html
<label for="msg">Message</label>
<textarea id="msg" name="message" maxlength=""></textarea>
```

### ❌ Invalid: non-numeric `maxlength` value

Strings, decimals, and negative numbers are also invalid.

```html
<label for="bio">Bio</label>
<textarea id="bio" name="bio" maxlength="none"></textarea>

<label for="notes">Notes</label>
<textarea id="notes" name="notes" maxlength="-1"></textarea>
```

### ✅ Fixed: specific integer value

Set `maxlength` to the desired character limit.

```html
<label for="msg">Message (max 200 characters)</label>
<textarea id="msg" name="message" maxlength="200"></textarea>
```

### ✅ Fixed: attribute omitted entirely

If no character limit is needed, simply remove the attribute.

```html
<label for="msg">Message</label>
<textarea id="msg" name="message"></textarea>
```

### ✅ Fixed: conditional rendering in a template

If you're using a templating engine, conditionally include the attribute only when a value exists. The exact syntax depends on your framework — here's a conceptual example:

```html
<!-- Instead of always outputting the attribute: -->
<!-- <textarea maxlength="{{ maxChars }}"></textarea> -->

<!-- Only render it when maxChars has a value: -->
<!-- {% if maxChars %}<textarea maxlength="{{ maxChars }}"></textarea>{% endif %} -->

<label for="feedback">Feedback</label>
<textarea id="feedback" name="feedback" maxlength="500"></textarea>
```
