diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ff143d196..9d957976ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
### Fixed
* [`no-array-index-key`]: consider flatMap ([#3530][] @k-yle)
* [`jsx-curly-brace-presence`]: handle single and only expression template literals ([#3538][] @taozhou-glean)
+* [`no-unknown-property`]: allow `onLoad` on `source` (@ljharb)
[#3538]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3538
[#3530]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3530
diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js
index de0404bfc1..dbb111a0ea 100644
--- a/lib/rules/no-unknown-property.js
+++ b/lib/rules/no-unknown-property.js
@@ -81,7 +81,7 @@ const ATTRIBUTE_TAGS_MAP = {
onEncrypted: ['audio', 'video'],
onEnded: ['audio', 'video'],
onError: ['audio', 'video', 'img', 'link', 'source', 'script', 'picture', 'iframe'],
- onLoad: ['script', 'img', 'link', 'picture', 'iframe', 'object'],
+ onLoad: ['script', 'img', 'link', 'picture', 'iframe', 'object', 'source'],
onLoadedData: ['audio', 'video'],
onLoadedMetadata: ['audio', 'video'],
onLoadStart: ['audio', 'video'],
diff --git a/tests/lib/rules/no-unknown-property.js b/tests/lib/rules/no-unknown-property.js
index 4ea068030c..97fb9f3dc1 100644
--- a/tests/lib/rules/no-unknown-property.js
+++ b/tests/lib/rules/no-unknown-property.js
@@ -65,7 +65,7 @@ ruleTester.run('no-unknown-property', rule, {
{ code: '' },
{ code: '' },
{ code: '' },
- { code: '' },
+ { code: '' },
{ code: '' },
{ code: '' },
{ code: '' },
@@ -459,7 +459,7 @@ ruleTester.run('no-unknown-property', rule, {
data: {
name: 'onLoad',
tagName: 'div',
- allowedTags: 'script, img, link, picture, iframe, object',
+ allowedTags: 'script, img, link, picture, iframe, object, source',
},
},
],