D2D file migration cannot processes a number of rows?
I just faced the same issue, and have a suspicion what the cause may be, though have not tested it.

I ran a migration of files in manual batches, e.g.

drush migrate-import MyMigration --limit="100 items"


several times. After the last batch (for which I did not specify an item limit, i.e. it should have imported all remaining unprocessed items), migrate-status still showed almost 900 unprocessed items. All calls thereafter to migrate-import would process 0 items, even with the --update flag -- which I thought should have either imported or updated (accordingly) ALL items...

Just as you did, I then queried for the source IDs it would not process. Upon inspection I noticed that large sets of them had the same exact timestamp (specifically, file_managed.timestamp column in the database). I recalled that Migrate can use a specified field to store a highwater mark for each migration, such that future import runs will only process items whose value of that field is greater than the stored highwater mark from previous runs. So for files, the timestamp value is used by default (per Migrate D2D implementation -- see DrupalFile7Migration::__construct()), and the query is ordered by timestamp ASC to cooperate with this.

I realized that the items it would not process were definitely older than the stored highwater timestamp (which is that of the newest item imported). Why then did Migrate not process those in an earlier batch, based on the query's order-by? Well... if many of my files had the same exact timestamp, the results of the query were not guaranteed to be in the same order across different runs. So if I was working with a limit of 100 items per run, but the results were not consistently ordered, it's possible some items never ended up falling within the batch (range of results) that was actually being imported at the time.

I'm not entirely sure if this could account for nearly 900 unprocessed images, but it's a thought.

Workaround

You can import items regardless of their status vs. the highwater mark by using the --idlist argument. So since you've queried to find the source IDs that won't process, just pass them as a comma-delimited string and I think it should work no matter what. Example:

drush migrate-import MyMigration --idlist="538,2891,485"


Actual fix? (untested)

If my suspicion is correct, then probably the solution is to order by not only timestamp, but additionally by fid, which is guaranteed unique, and thus the results order will be exactly the same every time. In your migration subclass, override query() and after calling the parent implementation, add $query-&gt;orderBy('fid', 'ASC'). This sets secondary ordering.