diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
--- a/django/contrib/admin/validation.py
+++ b/django/contrib/admin/validation.py
@@ -261,6 +261,19 @@
         if len(flattened_fieldsets) > len(set(flattened_fieldsets)):
             raise ImproperlyConfigured('There are duplicate field(s) in %s.fieldsets' % cls.__name__)
 
+    # exclude
+    if cls.exclude: # default value is None
+        check_isseq(cls, 'exclude', cls.exclude)
+        for field in cls.exclude:
+            check_formfield(cls, model, opts, 'exclude', field)
+            try:
+                f = opts.get_field(field)
+            except models.FieldDoesNotExist:
+                # If we can't find a field on the model that matches,
+                # it could be an extra field on the form.
+                continue
+        if len(cls.exclude) > len(set(cls.exclude)):
+            raise ImproperlyConfigured('There are duplicate field(s) in %s.exclude' % cls.__name__)
 
     # form
     if hasattr(cls, 'form') and not issubclass(cls.form, BaseModelForm):
diff --git a/tests/regressiontests/admin_validation/models.py b/tests/regressiontests/admin_validation/models.py
--- a/tests/regressiontests/admin_validation/models.py
+++ b/tests/regressiontests/admin_validation/models.py
@@ -71,6 +71,37 @@
     ...
 ImproperlyConfigured: 'InvalidFields.fields' refers to field 'spam' that is missing from the form.
 
+# Tests for basic validation of 'exclude' option values (#12689)
+
+>>> class ExcludedFields1(admin.ModelAdmin):
+...     exclude = ('foo')
+
+>>> validate(ExcludedFields1, Book)
+Traceback (most recent call last):
+    ...
+ImproperlyConfigured: 'ExcludedFields1.exclude' must be a list or tuple.
+
+>>> class ExcludedFields2(admin.ModelAdmin):
+...     exclude = ('name', 'name')
+
+>>> validate(ExcludedFields2, Book)
+Traceback (most recent call last):
+    ...
+ImproperlyConfigured: There are duplicate field(s) in ExcludedFields2.exclude
+
+>>> class ExcludedFieldsInline(admin.TabularInline):
+...     model = Song
+...     exclude = ('foo')
+
+>>> class ExcludedFieldsAlbumAdmin(admin.ModelAdmin):
+...     model = Album
+...     inlines = [ExcludedFieldsInline]
+
+>>> validate(ExcludedFieldsAlbumAdmin, Album)
+Traceback (most recent call last):
+    ...
+ImproperlyConfigured: 'ExcludedFieldsInline.exclude' must be a list or tuple.
+
 # Regression test for #9932 - exclude in InlineModelAdmin
 # should not contain the ForeignKey field used in ModelAdmin.model
 
