*/
    ProcessCopyOptions(NULL, true, other_options);
 
+   /*
+    * Filename is required for file_fdw foreign tables.  We must validate it
+    * separately because ProcessCopyOptions() doesn't validate it.
+    * We don't care whether the value is empty or not, because COPY doesn't
+    * care that.
+    */
+   if (catalog == ForeignTableRelationId && filename == NULL)
+       ereport(ERROR,
+               (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_REPLY),
+                errmsg("filename is required for file_fdw foreign tables")));
+
    PG_RETURN_VOID();
 }
 
        }
        prev = lc;
    }
+
+   /*
+    * The requirement of filename option must have been checked by
+    * file_fdw_validator at every DDL.  We check it here again just in case
+    * to avoid crash caused by unexpected catalog corruption.
+    */
    if (*filename == NULL)
-       ereport(ERROR,
-               (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_REPLY),
-                errmsg("filename is required for file_fdw foreign tables")));
+       elog(ERROR, "filename is required for file_fdw foreign tables");
+
    *other_options = options;
 }