McCarron's contract has a base value of $10 million and can be worth up to $16.5 million if he reaches playing-time incentives, a source said. The deal includes $6 million guaranteed, per source.
McCarron, 27, was a free agent after winning a grievance filed against the Cincinnati Bengals last year to determine whether he had been incorrectly put on the non-football injury list as a rookie. It was also determined that he was owed back pay for the time spent on the list in 2014.
McCarron played in seven regular-season games in 2015 and started three in place of Andy Dalton, completing 66.4 percent of his passes for 854 yards, six touchdowns and two interceptions. McCarron also started an AFC wild-card playoff game that season, completing 56.1 percent of his passes for one touchdown and one interception in an eventual a loss to the Pittsburgh Steelers.
McCarron has contended several times that he wants his chance to start somewhere, and it almost happened when the Browns attempted to send a second- and third-round pick to the Bengals in the fall. However, the paperwork didn't go through before the trade deadline and McCarron remained with Cincinnati for the 2017 season.
McCarron's signing comes after several veteran quarterbacks had found new teams in free agency this week, leaving Buffalo as perhaps the only remaining team that could offer him a chance to start this season.
The signing is unlikely to change the Bills' apparent plans to draft a quarterback next month. Buffalo owns the Nos. 12 and 21 overall picks, as well as two selections in each of the second and third rounds. The Bills could package those picks to trade up for one of the draft's top quarterbacks.
ESPN's Katherine Terrell contributed to this report.