I wrote a long question (and answer) just yesterday, that goes into depth on the why and how to solve this.
The point is, that you need to provide better starting values for the solver.
When you alow it to use its own (random) start point, for this cleass of model, you will often find a poor fit results.
fitmodel = @(a, x) cos(a.*x);
fitted = fit(t, y, fitmodel, 'TolX', 1E-15)
Here, a is estimated as less than 1, clearly a poor estimate. Even if I provide a start point of 2 for a, it gets it wrong.
fitted = fit(t, y, fitmodel, 'TolX', 1E-15, 'start',2)
try a little larger?
fitted = fit(t, y, fitmodel, 'TolX', 1E-15, 'start',3)
And that did it. I needed to start the solver out inside the basin of attraction before it will find the global solution.
For much more depth on the concepts here, read the question and answers I posted in that link.