The value of this changes to window in your inner function scope. Save a reference to the jQuery wrapper of your image when the outer function is triggered.
$('img').error(function() {
var $img = $(this);
setTimeout(function(){
$img.attr('src', $img.attr('src') + '?' + Math.random());
}, 3000);
});
Edit:
As @epascarello pointed out, you're assuming there aren't any existing query params already on the image when you append ?randomNum. If you know that will always be the case, that's fine, although the param really should be ?key=randomNum. If it's possible that there are existing params, you'll have to do something similar to the below. (But do you really need to append a random number to the URL?).
function updatedSrc(oldSrc) {
var delim = (oldSrc.indexOf('?') != -1) ? '&' : '?';
return oldSrc + delim + "rand=" + Math.random();
}
And when you update the src you would do $img.attr('src', updatedSrc($img.attr('src'))).